既然能够进行数据传输,那干脆再试着进行双向数据传输,就变成了简单的命令行聊天室一样,但是需要考虑几个问题
1:socket是否是双向数据传输,幸运的是肯定的
2:如果一端既发送又接收,如何调和的问题,不可能串行一前一后吧,这样发送和接收肯定无法都实时刷新结果,最简单的就是弄两个进程或者两个线程,一个发送一个接收,这里分别通过while(1)来持续操作
下面是分别通过多进程实现,code比较简单随意,主要实现功能:
server端:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 9999 #define MAXSIZE 4096 int main(){ int server_sockfd, connect_sockfd; struct sockaddr_in server_address; char buffer[MAXSIZE]; int recv_length; char eachline[MAXSIZE]; pid_t pid; if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ printf("server create socket failed!\n"); exit(1); } memset(&server_address, 0, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htons(PORT); if (bind(server_sockfd, (struct sockaddr *)&server_address, sizeof(server_address)) == -1){ printf("server bind failed!\n"); exit(1); } if (listen(server_sockfd, 10) == -1){ printf("server listen socket failed!\n"); exit(1); } if ((connect_sockfd = accept(server_sockfd, (struct sockaddr *)NULL, NULL)) == -1){ printf("server connect failed!\n"); exit(1); } printf("server connect sucessfully!\n"); memset(buffer, 0, MAXSIZE); if ((pid = fork()) < 0){ printf("server fork failed!\n"); exit(1); }else if (pid == 0){ while(1){ fgets(eachline, MAXSIZE, stdin); if (send(connect_sockfd, eachline, strlen(eachline), 0) == -1){ printf("server send failed!\n"); exit(1); } } }else{ while(1){ if ((recv_length = recv(connect_sockfd, buffer, MAXSIZE, 0)) == -1){ printf("server recv failed!\n"); exit(1); } buffer[recv_length] = '\0'; printf("server receive data: %s", buffer); } } close(connect_sockfd); close(server_sockfd); return 0; }
client端:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 9999 #define IPADDR "192.168.1.3" #define MAXSIZE 4096 int main(int argc, char **argv){ int client_sockfd; char buffer[MAXSIZE]; int recv_length; struct sockaddr_in server_address; char eachline[MAXSIZE]; pid_t pid; if ((client_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ printf("client create socket failed\n"); exit(1); } server_address.sin_family = AF_INET; server_address.sin_port = htons(PORT); if (inet_pton(AF_INET, IPADDR, &server_address.sin_addr) == -1){ printf("client inet_pton failed!\n"); exit(1); } if (connect(client_sockfd, (struct sockaddr *)&server_address, sizeof(server_address)) == -1){ printf("client connect failed!\n"); exit(1); } memset(buffer, 0, MAXSIZE); if ((pid = fork()) < 0){ printf("client fork failed!\n"); exit(1); }else if (pid == 0){ while(1){ if ((recv_length = recv(client_sockfd, buffer, MAXSIZE, 0)) == -1){ printf("client recv failed!\n"); exit(1); } buffer[recv_length] = '\0'; printf("client recv data: %s", buffer); } }else{ while(1){ fgets(eachline, MAXSIZE, stdin); if (send(client_sockfd, eachline, strlen(eachline), 0) == -1){ printf("client send data failed!\n"); exit(1); } //printf("client send sucessfully!\n"); } } close(client_sockfd); return 0; }
这里主进程和子进程一个发送一个接收,分别和对面持续进行数据传输
编译运行,注意的是还是必须要先执行服务端,因为监听listen是在服务端
服务端 [lihui@localhost ~]$ cc -o server server.c [lihui@localhost ~]$ ./server server connect sucessfully! server receive data: hello i love you server receive data: really? if sorry goodbye 光标 客户端 [lihui@localhost ~]$ cc -o client client.c [lihui@localhost ~]$ ./client hello client recv data: i love you really? client recv data: if client recv data: sorry client recv data: goodbye 光标
缺点就是,一段ctrl+c之后,另一方会打印满屏的信息,这是具体while(1)里打印问题