基于TCP协议的服务器,线程,多进程版本。
为了解决服务器可以同时和多个客户端数据交互。
代码如下:
server.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<wait.h>
#include<pthread.h>
typedef struct {
int sock;
int a;
}net_info;
void service(int sock,int a)
{
char buf[1024];
while(1)
{
buf[0] = 0;
ssize_t s = read(sock,buf,sizeof(buf)-1);
if(s > 0)
{
buf[s] = 0;
printf("我是 %d : %s\n",a,buf);
write(sock,buf,strlen(buf));
}
else if(s ==0)
{
printf("client %d quit\n",a);
break;
}
else{
printf("read error!\n");
break;
}
}
}
//线程处理函数
void *rout(void *arg)
{
net_info* tmp = (net_info*)arg;
service(tmp->sock,tmp->a);
close(tmp->sock);
free(tmp);
}
//./server 0 8080
int main(int argc,char *argv[])
{
if(argc != 3)
{
printf("usage: ./client [ip] [port]");
return 1;
}
//创建文件描述符
int sock = socket(AF_INET,SOCK_STREAM,0);
if(sock < 0)
{
printf("create socket error\n");
return 2;
}
struct sockaddr_in server_socket;
server_socket.sin_family = AF_INET;
server_socket.sin_port = htons(atoi(argv[2]));
server_socket.sin_addr.s_addr = inet_addr(argv[1]);
//绑定文件描述符,IP/PORT
if(bind(sock,(struct sockaddr*)&server_socket,sizeof(struct sockaddr_in))<0)
{
printf("bind error\n");
goto END;
}
int ret = listen(sock,5);
if(ret < 0)
{
printf("listen error\n");
goto END;
}
printf("bind and listen success..\n");
struct sockaddr_in peer;
while(1)
{
socklen_t len = sizeof(peer);
int new_sock = accept(sock,(struct sockaddr*)&peer,&len);
if(new_sock<0)
{
printf("accept error\n");
continue;
}
net_info *info = (net_info *)malloc(sizeof(net_info));
if(info == 0)
{
perror("malloc\n");
close(new_sock);
continue;
}
info->sock = new_sock;
info->a = new_sock;
//线程
pthread_t tid;
pthread_create(&tid,NULL,rout,(void *)info);
pthread_detach(tid);
/*
// 多进程
pid_t pid = fork();
if(pid == 0)
{
//child
close(sock);
if(fork() > 0)
{
exit(0);
}
service(new_sock,a);
close(new_sock);
exit(0);
}
else if(pid > 0)
{
close(new_sock);
waitpid(pid,NULL,0);
}
else{
printf("fork error\n");
continue;
}
*/
}
END:
close(sock);
return 0;
}
运行结果:
支持多个客户端同时访问。