比较网络程序的优缺点:
多进程:
缺点:
1.链接来后才创建子进程,性能受损
2.进程消耗资源,只能受理有限个服务
3.调度压力增大,影响性能
优点:
1.处理多个任务
2.编写周期短
3.独立性、稳定性强
多进程(共享文件描述符):
缺点:
1.链接来后才创建子进程,性能受损
2.进程消耗资源,只能受理有限个服务
3.调度压力增大,影响性能
优点:
1.处理多个任务
2.编写周期短
3.独立性、稳定性强 但有可能由于线程安全问题挂掉
以下是多线程网络程序
//服务器
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<stdlib.h>
#include <arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
#define MAX 128
typedef struct
{
int sock;
char ip[24];
int port;
}net_info_t;
void service(int sock,char* ip,int port)
{
char buf[MAX];
while(1)
{
buf[0] = 0;
ssize_t s = read(sock,buf,sizeof(buf)-1);
if(s > 0)
{
buf[s] = 0;
printf("[%s:%d] say# %s\n",ip,port,buf);
write(sock,buf,strlen(buf));
}
else if(s == 0)
{
printf("client [%s:%d] quit\n",ip,port);
break;
}
else
{
printf("read error\n");
break;
}
}
}
int statup(char* ip,int port)
{
int sock = socket(AF_INET,SOCK_STREAM,0);
if(sock < 0)
{
printf("socket error\n");
exit(2);
}
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_addr.s_addr = inet_addr(ip);
local.sin_port = htons(port);
if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0)
{
printf("bind error\n");
exit(3);
}
if(listen(sock,5) < 0)
{
printf("listen error\n");
exit(4);
}
return sock;
}
void *thread_service(void* arg)
{
net_info_t *p = (net_info_t*)arg;
service(p->sock,p->ip,p->port);
close(p->sock);
free(p);
}
// ./tcpServer 127.0.0.1 8080
int main(int argc,char* argv[])
{
if(argc != 3)
{
printf("Usage: %s[ip][port]\n",argv[0]);
return 1;
}
int listen_sock = statup(argv[1],atoi(argv[2]));
struct sockaddr_in peer;
char ipBuf[24];
for(;;)
{
ipBuf[0] = 0;
socklen_t len = sizeof(peer);
int new_sock = accept(listen_sock,(struct sockaddr*)&peer,&len);
if(new_sock < 0)
{
printf("accept error\n");
continue;
}
inet_ntop(AF_INET,(const char*)&peer.sin_addr,ipBuf,sizeof(ipBuf));
int port = ntohs(peer.sin_port);
printf("get a new connet,[%s:%d]\n",ipBuf,port);
net_info_t *info = (net_info_t*)malloc(sizeof(net_info_t));
if(info == NULL)
{
perror("malloc");
close(new_sock);
continue;
}
info->sock = new_sock;
strcpy(info->ip,ipBuf);
info->port = port;
pthread_t tid;
pthread_create(&tid,NULL,thread_service,(void*)info);
pthread_detach(tid);//线程分离
//service(new_sock,ipBuf,port);
//close(new_sock);
}
return 0;
}
//客户端
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<stdlib.h>
#include <arpa/inet.h>
#include<unistd.h>
#include<string.h>
#define MAX 128
// ./tcpClient 127.0.0.1 8080
int main(int argc,char* argv[])
{
if(argc != 3)
{
printf("Usage: %s [ip] [port]\n",argv[0]);
exit(1);
}
int sock = socket(AF_INET,SOCK_STREAM,0);
if(sock < 0)
{
printf("socket error\n");
exit(2);
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
server.sin_addr.s_addr = inet_addr(argv[1]);
if(connect(sock,(struct sockaddr*)&server,sizeof(server)) < 0)
{
printf("connect error\n");
exit(3);
}
char buf[MAX];
while(1)
{
printf("please Enter# ");
fflush(stdout);
ssize_t s = read(0,buf,sizeof(buf)-1);
if(s > 0)
{
buf[s-1] = 0;
if(strcmp("quit",buf) == 0)
{
printf("client quit\n");
break;
}
write(sock,buf,strlen(buf));
s = read(sock,buf,sizeof(buf)-1);
buf[s] = 0;
printf("Server Echo %s\n",buf);
}
}
close(sock);
return 0;
}
[root@localhost consumer]# netstat -nlpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1/systemd
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 8964/./tcpServer