既然能够进行数据传输,那干脆再试着进行双向数据传输,就变成了简单的命令行聊天室一样,但是需要考虑几个问题
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)里打印问题
