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
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