socket服务端和客户端实现多方消息收发
相关函数
(1)socket()函数
int socket(int domain, int type, int protocol);
(2)bind()函数: IP号端口号与相应描述字赋值函数
int bind(int sockfd, const struct sockaddr *addr,socklen t addrlen);
功能
用于绑定 IP 地址和端口号到 socketfd
参数
sockfd
是一个 socket 描述符
addr
是一个指向包含有本机 IP 地址及端口号等信息的 sockaddr 类型的指指向要绑定给 sockfd 的协议地址结构,这个地址结构根据地址创建 socket 时的地址协议族的不同而不同
struct sockaddr{ unisgned short as_family; //协议族 char sa_data[14]; //IP+端口 }; 同等替换 struct sockaddr_in { sa_family_t sin_family; //协议族 in_port_t sin_port; //端口号 struct in_addr sin_addr; //IP地址结构体 unsigned char sin_zero[8]; //没有实际意义只是为跟sockaddr结构在内存中对亮这样两者才能相互转换 }
(3)listen()函数:监听设置函数
int listen(int sockfd, int backlog);
(4)accept()函数
int accept(int sockfd, struct sockaddr *addr, socklen t *addrlen);
服务端代码实现:
#include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> //#include <linux/in.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> int main(int argc, char **argv) { int s_fd; int c_fd; int n_read; char readBuf[128]; int mark = 0; char msg[128] = {0}; // char *msg = "I get your connect"; struct sockaddr_in s_addr; struct sockaddr_in c_addr; if(argc != 3){ printf("param is not good\n"); exit(-1); } memset(&s_addr,0,sizeof(struct sockaddr_in)); memset(&c_addr,0,sizeof(struct sockaddr_in)); //1. socket s_fd = socket(AF_INET, SOCK_STREAM, 0); if(s_fd == -1){ perror("socket"); exit(-1); } s_addr.sin_family = AF_INET; s_addr.sin_port = htons(atoi(argv[2])); inet_aton(argv[1],&s_addr.sin_addr); //2. bind bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in)); //3. listen listen(s_fd,10); //4. accept int clen = sizeof(struct sockaddr_in); while(1){ c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen); if(c_fd == -1){ perror("accept"); } mark++; printf("get connect: %s\n",inet_ntoa(c_addr.sin_addr)); if(fork() == 0){ if(fork()==0){ while(1){ sprintf(msg,"welcom No.%d client",mark); write(c_fd,msg,strlen(msg)); sleep(3); } } //5. read while(1){ memset(readBuf,0,sizeof(readBuf)); n_read = read(c_fd, readBuf, 128); if(n_read == -1){ perror("read"); }else if(n_read>0){ printf("\nget:%s\n",readBuf); }else{ printf("client quit\n"); break; } } break; } } return 0; }
客户端代码实现:
#include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> //#include <linux/in.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> int main(int argc, char **argv) { int c_fd; int n_read; char readBuf[128]; int tmp; // char *msg = "msg from client"; char msg[128] = {0}; struct sockaddr_in c_addr; memset(&c_addr,0,sizeof(struct sockaddr_in)); if(argc != 3){ printf("param is not good\n"); exit(-1); } printf("%d\n",getpid()); //1. socket c_fd = socket(AF_INET, SOCK_STREAM, 0); if(c_fd == -1){ perror("socket"); exit(-1); } c_addr.sin_family = AF_INET; c_addr.sin_port = htons(atoi(argv[2])); inet_aton(argv[1],&c_addr.sin_addr); //2.connect if(connect(c_fd, (struct sockaddr *)&c_addr,sizeof(struct sockaddr)) == -1){ perror("connect"); exit(-1); } while(1){ if(fork()==0){ while(1){ memset(msg,0,sizeof(msg)); printf("input: "); gets(msg); write(c_fd,msg,strlen(msg)); } } while(1){ memset(readBuf,0,sizeof(readBuf)); n_read = read(c_fd, readBuf, 128); if(n_read == -1){ perror("read"); }else{ printf("\nget:%s\n",readBuf); } } } //3.send //4.read return 0; }
编译结果:
连接一个
、
连接两个