Linux基础网络编程:Linux环境下TCP服务器与客户端的搭建
在Linux下创建一个tcp服务器,有以下六个步骤:socket– 创建套接字bind– 绑定主机和端口listen--设置监听套接字accept– 接收客户端连接,并生成新的套接字read/write– 收发数据close– 关闭套接字简单介绍一下这几个函数:1.socket:创建套接字#include <sys/types.h>/* See NOTES */#include <
·
在Linux下创建一个tcp服务器,有以下六个步骤:
- socket – 创建套接字
- bind – 绑定主机和端口
- listen --设置监听套接字
- accept – 接收客户端连接,并生成新的套接字
- read/write – 收发数据
- close – 关闭套接字
创建客户端要简单的多,主要分为以下几步:
- socket --创建套接字
- connect --主动连接服务器
- write/read --发收数据
- close --关闭套接字
简单介绍一下这几个函数:
1.socket:创建套接字
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
参数:
domain: 地址族
AF_INET --- IPv4 internet protocols
type: 套接字类型
SOCK_STREAM --- 流式套接字(TCP)
SOCK_DGRAM --- 数据报套接字(UDP)
SOCK_RAW --- 原始套接字(IP层)
protocol --- 通常为0
返回值:
成功: 套接字文件描述符
失败: -1, 并设置errno
2.bind : 绑定主机地址和端口
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:sockfd --- 套接字文件描述符
addr --- 本机的地址
addrlen --- 本机的地址长度
返回值:
成功: 0
失败: -1, 并设置errno
通用地址结构:
struct sockaddr {
sa_family_t sa_family; //地址族
char sa_data[14];
}
Internet地址结构:
struct sockaddr_in {
u_short sin_family; // 地址族, AF_INET,2 bytes
u_short sin_port; // 端口,2 bytes
struct in_addr sin_addr; // IPV4地址,4 bytes
char sin_zero[8]; // 8 bytes unused,作为填充
};
IPv4地址结构
// internet address
struct in_addr
{
in_addr_t s_addr; // u32 network address
};
3.listen:设置监听套接字
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
参数:sockfd --- 套接字文件描述符
backlog --- 监听队列长度
返回值:
成功: 0
失败: -1, 并设置errno
4.accept:接收客户端连接,并生成通信套接字
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数:
sockfd --- 套接字文件描述符
addr --- 客户端的地址
addrlen --- 客户端的地址长度
注: addr和addrlen用于获取客户端的地址,如果不需要知道客户端,则这两个参数置为NULL
返回值:
成功: 通信套接字
失败: -1,设置errno
5.connect:主动连接服务器(客户端)
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:
sockfd --- 套接字文件描述符
addr --- 服务器的地址
addrlen--- addr的长度
返回值:
成功: 0
失败: -1, 并设置errno
6.send:向套接字中发送数据
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
参数:
sockfd --- 套接字文件描述符
buf --- 发送数据的首地址
len --- 发送的字节数
flags --- 发送方式(0)
返回值:
成功: 成功发送的字节数
失败: -1, 并设置errno
7.recv:从套接字中接收数据
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
参数: sockfd --- 套接字文件描述符
buf --- 存放数据的空间首地址
len --- 想要接收的字节数
flags --- 接收方式(0)
返回值:
>0: 成功接收的字节数
=0:发送端关闭
-1:失败,并设置errno
创建一个tcp服务器:
server.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int main(void)
{
//1.创建套接字
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
perror("socket");
return -1;
}
printf("socket create success..................\n");
//2.绑定本机地址和端口
struct sockaddr_in myaddr;
memset(&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(6666);//端口号
myaddr.sin_addr.s_addr = inet_addr("127.0.0.1");//本机IP地址
int ret = bind(sockfd,(struct sockaddr*)&myaddr,sizeof(myaddr));
if(ret < 0){
perror("bind:");
goto err;
}
//3.设置监听套接字
ret = listen(sockfd,8);
if(ret < 0){
perror("listen:");
goto err;
}
printf("listen...............\n");
//4.接收客户端连接,并生成通信套接字
int connfd = accept(sockfd, NULL, NULL);
if(connfd < 0){
perror("accept:");
goto err;
}
//5.收发数据
char buf[1024];
while(1){
memset(buf,0,sizeof(buf));
ret = read(connfd,buf,sizeof(buf));
if(ret < 0){
perror("read:");
break;
}else if(ret == 0){
printf("write close!\n");
break;
}else{
printf("recv:%s\n",buf);
}
}
//6.关闭套接字
close(sockfd);
close(connfd);
err:
close(sockfd);
return -1;
}
client.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int main()
{
//1.创建套接字
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
perror("socket:");
return -1;
}
printf("client socket create success........\n");
//2.主动连接服务器
struct sockaddr_in srvaddr;
memset(&srvaddr, 0, sizeof(srvaddr));
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(6666);
srvaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int ret = connect(sockfd,(struct sockaddr*)&srvaddr,sizeof(srvaddr));
if(ret < 0){
perror("connect");
close(sockfd);
return -1;
}
//3.发送数据
char buf[1024];
while(1){
printf("send: ");
fgets(buf,sizeof(buf),stdin);
ret = write(sockfd,buf,sizeof(buf));
if(ret < 0){
perror("write");
break;
}
if(strncmp(buf,"quit",4) == 0){
break;
}
}
//4.关闭套接字
close(sockfd);
return 0;
}
现在客户端与服务器已经可以连接,并且可以从客户端发送消息,服务器接收消息。
更多推荐
已为社区贡献1条内容
所有评论(0)