Linux tcp客户端断开重连,Linux网络编程——TCP和UDP通信

TCP协议流程图、TCP建立即时聊天

TCP即时聊天升级:服务器在客户端断开后不断开,客户端可以多次重连服务器进行即时聊天

UDP协议流程图、UDP建立即时连接

如果在已经处于 ESTABLISHED状态下的socket(一般由端口号和标志符区分)需调用closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket,但也可以直接用setsockopt和reuse。

SO_RCVLOWAT设置接收缓冲区下限

1、TCP协议的流程图

服务端:socket---bind---listen---while(1){---accept---recv---send---close---}---close

客户端:socket----------------------------------connect---send---recv-----------------close

L3Byb3h5L2h0dHAvaW1hZ2UubWFtaWNvZGUuY29tL2luZm8vMjAxOTA1LzIwMTkwNTAyMjMzNTUwNjQwMjM0LnBuZw==.jpg

TCP建立即时聊天

tcp_client.c

#include

int main(int argc,char* argv[])

{

ARGS_CHECK(argc,3);

int socketFd;

socketFd=socket(AF_INET,SOCK_STREAM,0);

ERROR_CHECK(socketFd,-1,"socket");

struct sockaddr_in ser;

bzero(&ser,sizeof(ser));

ser.sin_family=AF_INET;

ser.sin_port=htons(atoi(argv[2]));

ser.sin_addr.s_addr=inet_addr(argv[1]);//点分十进制转为32位的网络字节序

int ret;

ret=connect(socketFd,(struct sockaddr*)&ser,sizeof(ser));

ERROR_CHECK(ret, -1, "connect");

printf("connect success\n");

char buf[128]={0};

fd_set rdset;

while(1){

FD_ZERO(&rdset);

FD_SET(STDIN_FILENO, &rdset);

FD_SET(socketFd, &rdset);

ret = select(socketFd + 1, &rdset, NULL, NULL, NULL);

if(FD_ISSET(socketFd, &rdset)){

bzero(buf, sizeof(buf));

ret = recv(socketFd, buf, sizeof(buf), 0);

ERROR_CHECK(ret, -1, "recv");

if(ret == 0){

printf("byebye!\n");

break;

}

printf("%s\n", buf);

}

if(FD_ISSET(STDIN_FILENO, &rdset)){

memset(buf, 0, sizeof(buf));

ret = read(STDIN_FILENO, buf, sizeof(buf));

if(ret == 0){

printf("byebye!\n");

break;

}

ret = send(socketFd, buf ,strlen(buf) - 1, 0);

ERROR_CHECK(ret, -1, "send");

}

}

close(socketFd);

}

tcp_server.c

#include

int main(int argc,char* argv[])

{

ARGS_CHECK(argc,3);

int socketFd;

socketFd = socket(AF_INET,SOCK_STREAM,0);

ERROR_CHECK(socketFd, -1, "socket");

struct sockaddr_in ser;

bzero(&ser, sizeof(ser));

ser.sin_family = AF_INET;

ser.sin_port = htons(atoi(argv[2]));

ser.sin_addr.s_addr = inet_addr(argv[1]);//点分十进制转为32位的网络字节序

int ret;

ret = bind(socketFd, (struct sockaddr*)&ser, sizeof(ser));

ERROR_CHECK(ret, -1, "bind");

listen(socketFd, 10);//缓冲区的大小,一瞬间能够放入的客户端连接信息

int new_fd;

struct sockaddr_in client;

bzero(&client, sizeof(client));

int addrlen = sizeof(client);

new_fd = accept(socketFd, (struct sockaddr*)&client, &addrlen);

ERROR_CHECK(new_fd, -1, "accept");

printf("client ip=%s, port=%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));

fd_set rdset;

char buf[128] = {0};

while(1){

FD_ZERO(&rdset);

FD_SET(STDIN_FILENO, &rdset);

FD_SET(new_fd, &rdset);

ret = select(new_fd + 1, &rdset, NULL, NULL, NULL

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值