服务端socket流程:socket() –> bind() –> listen() –> accept() –> 读取、发送信息(recv,send等)
客户端socket流程:socket() –> connect() –> 发送、读取信息(send,recv等)
参考:Socket基本操作
本文包含基本实现,多线程版本
基本实现
服务端监听某个端口,客户端连接之后发送数据——>客户端断开连接后,服务端也关闭了
服务端:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/socket.h> 4 #include <netinet/in.h> 5 #include <string.h> 6 7 const int Port = 8888; 8 9 int main(void){ 10 int sock_fd; 11 struct sockaddr_in mysock; 12 struct sockaddr_in client_addr; 13 int new_fd; 14 socklen_t sin_size 15 char buf[1024]; 16 char sedbuf[1024] = "recv successfully.\n"; 17 18 //初始化socket 19 sock_fd = socket(AF_INET,SOCK_STREAM,0); 20 21 //编辑地址信息 22 memset(&mysock,0,sizeof(mysock)); 23 mysock.sin_family = AF_INET; 24 mysock.sin_port = htons(Port); 25 mysock.sin_addr.s_addr = INADDR_ANY; 26 27 //绑定地址,然后监听 28 bind(sock_fd,(struct sockaddr *)&mysock,sizeof(struct sockaddr)); 29 if(listen(sock_fd,10) < -1){ 30 printf("listen error.\n"); 31 } 32 33 sin_size = sizeof(struct sockaddr_in); 34 35 printf("listening...\n"); 36 new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);//accpet 37 while(1){ 38 int len = recv(new_fd,buf,sizeof(buf),0); 39 fputs(buf,stdout); 40 send(new_fd, sedbuf, sizeof(sedbuf), 0); 41 if(strcmp(buf,"exit\n") == 0){ 42 break; 43 } 44 memset(buf,0,sizeof(buf)); 45 } 46 close(new_fd); 47 close(sock_fd); 48 return 0;
客户端:
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<stdlib.h> 4 #include<sys/types.h> 5 #include<sys/socket.h> 6 #include<netinet/in.h> 7 #include<netdb.h> 8 #include<string.h> 9 #include<errno.h> 10 11 const int Port = 8888; 12 13 int main(void){ 14 int sock_fd; 15 char buf[1024], sendbuf[1024], recvbuf[1024]; 16 struct sockaddr_in server_addr; 17 sock_fd = socket(AF_INET, SOCK_STREAM, 0);//初始化socket 18 if(sock_fd == -1){ 19 printf("%s\n",strerror(errno)); 20 return 0; 21 } 22 23 bzero(&server_addr, sizeof(server_addr));//编辑服务端地址信息 24 server_addr.sin_family = AF_INET; 25 server_addr.sin_port = htons(Port); 26 server_addr.sin_addr.s_addr = htonl(INADDR_ANY); 27 28 int tmp = connect(sock_fd, (struct sockaddr *)(&server_addr), 29 sizeof(struct sockaddr));//连接服务端socket 30 if(tmp == -1){ 31 printf("%s\n",strerror(errno)); 32 return 0; 33 } 34 35 while(1){ 36 fgets(sendbuf, sizeof(sendbuf), stdin); 37 send(sock_fd, sendbuf, strlen(sendbuf), 0); 38 if(strcmp(sendbuf, "exit\n") == 0) 39 break; 40 recv(sock_fd, recvbuf, sizeof(recvbuf), 0); 41 fputs(recvbuf, stdout); 42 memset(sendbuf, 0, sizeof(sendbuf)); 43 memset(recvbuf, 0, sizeof(recvbuf)); 44 } 45 close(sock_fd); 46 return; 47 }
多客户端与服务端通信(多线程)
只需在服务端修改,增加多线程,就可以同时接收多个客户端发送的信息了。
服务端:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/socket.h> 4 #include <netinet/in.h> 5 #include <string.h> 6 #include <pthread.h> 7 #include <unistd.h> 8 9 const int Port = 8888; 10 pthread_mutex_t g_mutext; 11 12 struct pthread_data{ 13 struct sockaddr_in client_addr; 14 int sock_fd; 15 }; 16 17 void *serveForClient(void * arg); 18 19 int main(void){ 20 int sock_fd; 21 struct sockaddr_in mysock; 22 struct pthread_data pdata; 23 pthread_t pt; 24 socklen_t sin_size = sizeof(struct sockaddr_in); 25 struct sockaddr_in client_addr; 26 int new_fd; 27 28 //初始化socket 29 sock_fd = socket(AF_INET,SOCK_STREAM,0); 30 31 //编辑地址信息 32 memset(&mysock, 0, sizeof(mysock)); 33 mysock.sin_family = AF_INET; 34 mysock.sin_port = htons(Port); 35 mysock.sin_addr.s_addr = INADDR_ANY; 36 37 //绑定地址,然后监听 38 bind(sock_fd,(struct sockaddr *)&mysock,sizeof(struct sockaddr)); 39 if(listen(sock_fd,10) < -1){ 40 printf("listen error.\n"); 41 } 42 43 printf("listening...\n"); 44 while(1){ 45 //accpet 46 new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size); 47 pdata.client_addr = client_addr; 48 pdata.sock_fd = new_fd; 49 pthread_create(&pt, NULL, serveForClient, (void *)&pdata); 50 } 51 close(new_fd); 52 close(sock_fd); 53 return 0; 54 } 55 56 void *serveForClient(void *arg){ 57 struct pthread_data *pdata = (struct pthread_data*)arg; 58 int new_fd = pdata->sock_fd; 59 char recvbuf[1024]; 60 char sendbuf[1024] = "recv successfully.\n"; 61 while(1){ 62 recv(new_fd, recvbuf, sizeof(recvbuf), 0); 63 fputs(recvbuf,stdout); 64 strcpy(sendbuf, recvbuf); 65 if(strcmp(recvbuf,"exit\n") == 0){ 66 send(new_fd, "connection close.\n", sizeof("connection close.\n"), 0); 67 break; 68 } 69 send(new_fd, sendbuf, sizeof(sendbuf), 0); 70 memset(recvbuf,0,sizeof(recvbuf)); 71 } 72 close(new_fd); 73 pthread_exit(0); 74 }