码迷,mamicode.com
首页 > 编程语言 > 详细

Linux统系统开发11 Socket API编程2 多进程 多线程 高并发处理

时间:2016-08-19 22:27:23      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:linux统系统开发11 socket api编程2 多进程 多线程 高并发处理

本文谢绝转载原文来自http://990487026.blog.51cto.com

<纲要>

Linux统系统开发11 Socket API编程2 多进程 多线程 高并发处理
	UDP服务器 客户端最小模型,处理字符转大写
	TCP 多进程并发服务器模型,为每个客户端开启一个进程:
	TCP 多线程服务器模型,使用wrap函数封装
	作业:	

----------------------------------------------------

UDP服务器 客户端最小模型,处理字符转大写

chunli@ubuntu:~/linux_c/network_2$ cat server_udp.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <unistd.h>
#include <ctype.h>

#define SERVER_PORT 8000

int main(void)
{
	int sockfd;
	struct sockaddr_in	serveraddr;
	struct sockaddr_in	clientaddr;
	char buf[1024];
	int len = 0;
	socklen_t socketlen = 0;
	//char ipstr[INET6_ADDRSTRLEN];	//ipV6字符串
	char ipstr[INET_ADDRSTRLEN];	//ipV4字符串最大16个字符
	int strlen = 0;

	sockfd = socket(AF_INET,SOCK_DGRAM,0);	//构建用于UDP通信的套接字
	bzero(&serveraddr,sizeof(serveraddr));	//清零结构体数据
	serveraddr.sin_family = AF_INET;	//IPV4
	serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);//允许来自本地任意IP的请求,INADDR_ANY 就是0
	serveraddr.sin_port = htons(SERVER_PORT);
	bind(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
	while(1)
	{
		socketlen = sizeof(clientaddr);//初始化
		len = recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&clientaddr,&socketlen);	//clientaddr客户机信息
		inet_ntop(AF_INET,&clientaddr.sin_addr.s_addr,ipstr,sizeof(ipstr));//大端转本地 ip地址
		ntohs(clientaddr.sin_port);	//转端口
		printf("client ip:%s  port:%d\n",ipstr,0);
		int i = 0;
		while(i < len)
		{
			buf[i] = toupper(buf[i]);
			i++;
		}
		sendto(sockfd,buf,len,0,(struct sockaddr*)&(clientaddr),sizeof(clientaddr));
	}
	close(sockfd);

	return 0;
}

chunli@ubuntu:~/linux_c/network_2$ gcc -o server_udp server_udp.c &&  ./server_udp
chunli@ubuntu:~/linux_c/network_2$ cat client_udp.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define  SERVER_PORT 8000

int main(int argc,char **argv)
{
	if(argc < 2)
	{
		printf("to few argc \n");
		exit(1);
	}
	struct sockaddr_in serveraddr;
	int clientfd;
	char buf[4096];
	char ipstr[] = "11.11.11.3 ";   //服务器IP
	//1创建socket
	clientfd = socket(AF_INET,SOCK_DGRAM,0); //UDP
	//2初始化服务器地址
	bzero(&serveraddr,sizeof(serveraddr));
	serveraddr.sin_family  =AF_INET;
	inet_pton(AF_INET,ipstr,&serveraddr.sin_addr.s_addr);
	serveraddr.sin_port = htons(SERVER_PORT);
	//3连接服务器
	//udp不需要连接服务器

	//4 请求服务器处理数据
	int i = 1;
	while(i < argc)
	{
		bzero(buf,sizeof(buf));
		sendto(clientfd,argv[i],strlen(argv[i]),0,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
		recvfrom(clientfd,buf,sizeof(buf),0,NULL,0);
		printf("%s ",buf);
		i++;
	}
	printf("\n");



	//5 关闭socket
	close(clientfd);



	return 0;
}

chunli@ubuntu:~/linux_c/network_2$ gcc -o client_udp   client_udp.c &&  ./client_udp Hello World! Linux 
HELLO WORLD! LINUX 
chunli@ubuntu:~/linux_c/network_2$ gcc -o client_udp   client_udp.c &&  ./client_udp lichunli
LICHUNLI 
chunli@ubuntu:~/linux_c/network_2$




服务端的输出

chunli@ubuntu:~/linux_c/network_2$ gcc -o server_udp server_udp.c &&  ./server_udp
client ip:127.0.0.1  port:0
client ip:127.0.0.1  port:0
client ip:127.0.0.1  port:0
client ip:127.0.0.1  port:0


-----------------------------------------------------



TCP 多进程并发服务器模型

TCP 多进程并发服务器模型,为每个客户端开启一个进程:


使用多进程并发服务器时要考虑以下几点:


1.父最大文件描述个数(父进程中需要close关闭accept返回的新文件描述符)


2.系统内创建进程个数(内存大小相关)


3.进程创建过多是否降低整体服务性能(进程调度)



1,服务端程序:

chunli@ubuntu:~/linux_c/m_fork$ cat server.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <ctype.h>
#include <unistd.h>
#include <arpa/inet.h>
int main(void)
{
	struct sockaddr_in	serveraddr;
	struct sockaddr_in	clientaddr;
	int socketfd;
	int clientfd;
	int addrlen;
	int port;
	char ipstr[128];
	char buf[4096];	//字符缓冲
	int len = 0;
	pid_t pid;	//多线程

	//1.socket
	socketfd = socket(AF_INET,SOCK_STREAM,0);	//建立TCP
	//2.bind
	bzero(&serveraddr,sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;		//地址族协议IPV4
	serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);	//IP地址
	serveraddr.sin_port = htons(8000);		//端口
	bind(socketfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
	//3.listen
	listen(socketfd,128);
	while(1)
	{
		//4.appept阻塞模式监听
		addrlen = sizeof(clientaddr);
		clientfd = accept(socketfd,(struct sockaddr*)&clientaddr,(socklen_t*)&addrlen);//发返回客户端socket

		//输出客户端Ip地址 和端口号
		inet_ntop(AF_INET,&clientaddr.sin_addr.s_addr,ipstr,sizeof(ipstr));//ip数字转字符
		port = ntohs(clientaddr.sin_port);	//大端转小端
		printf("client ip %s ,port:%d \n",ipstr,port);

		//多进程处理客户请求
		pid = fork();
		if(pid == 0)	//子进程
		{	
			close(socketfd);//关闭子进程的监听
			while(1)
			{
				//处理客户请求
				len = read(clientfd,buf,sizeof(buf));
				int i = 0;
				while(i < len)
				{
					buf[i] = toupper(buf[i]);
					i++;
				}
				write(clientfd,buf,len);
			}			
			//5再见
			close(clientfd);
			return 0;
		}
		else if(pid > 0)	//父进程
		{
			close(clientfd);//关闭父进程的客户端socket
		}
		else 
		{
			perror("fork");
			exit(1);
		}
	}
	close(socketfd);
	return 0;
}
chunli@ubuntu:~/linux_c/m_fork$ gcc server.c  -o server -Wall  &&  ./server




再开一个本机窗口,查看监听8000:(因为程序过于简陋,有时候起可能起不来)
chunli@ubuntu:~/linux_c/m_fork$ netstat -tnlp
(并非所有进程都能被检测到,所有非本用户的进程信息将不会显示,如果想看到所有信息,则必须切换到 root 用户)
激活Internet连接 (仅服务器)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.1.1:53            0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      8193/server     
tcp6       0      0 :::22                   :::*                    LISTEN      -               
chunli@ubuntu:~/linux_c/m_fork$



客户端程序:

chunli@ubuntu:~/linux_c/m_fork$ cat client.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define  SERVER_PORT 8000

int main(int argc,char **argv)
{
//	if(argc < 2)
//	{
//		printf("to few argc \n");
//		exit(1);
//	}
//
	struct sockaddr_in serveraddr;
	int clientfd;
	char buf[4096];
	char ipstr[] = "11.11.11.3";	//服务器IP
	//write(STDOUT_FILENO,ipstr,strlen(ipstr)+1);	exit(1);
	//1创建socket
	clientfd = socket(AF_INET,SOCK_STREAM,0);	//TCP
	//2初始化服务器地址
	bzero(&serveraddr,sizeof(serveraddr));
	serveraddr.sin_family  =AF_INET;
	inet_pton(AF_INET,ipstr,&serveraddr.sin_addr.s_addr);
	serveraddr.sin_port = htons(SERVER_PORT);
	//3连接服务器
	connect(clientfd,(const struct sockaddr *)&serveraddr,sizeof(serveraddr));
	
	//4 请求服务器处理数据
	while(1)
	{
		fgets(buf,sizeof(buf),stdin);			
		write(clientfd,buf,strlen(buf));	
		int len = read(clientfd,buf,sizeof(buf));
		write(STDOUT_FILENO,buf,len);
		//printf("%s\n",buf);
	}
	
	//5 关闭socket
	close(clientfd);



	return 0;
}


在局域网内的其他linux主机跑一跑:

chunli@ubuntu:~/linux_c/m_fork$ gcc client.c -o client  -Wall -g  && ./client 
haha
HAHA
lslsls
LSLSLS


局域网其他主机跑的结果:

chunli@ubuntu14:~/m_fork$ gcc client.c -o client -Wall -g  && ./client 
opopop
OPOPOP
Hello World!
HELLO WORLD!

再回来看看服务端输出的信息:

chunli@ubuntu:~/linux_c/m_fork$ gcc server.c  -o server -Wall  &&  ./server
client ip 11.11.11.3 ,port:35218 
client ip 11.11.11.8 ,port:41416

数据反映了有两个客户端在耍闹。


【程序bug】客户端断开之后,服务端3个进程还在运行:

chunli@ubuntu:~$ ps aux | grep ./server
chunli     8368  0.0  0.0   4356   640 pts/14   S+   14:40   0:00 ./server
chunli     8376  0.0  0.0   4356    92 pts/14   S+   14:40   0:00 ./server
chunli     8384  0.0  0.0   4356    92 pts/14   S+   14:41   0:00 ./server
chunli     8388  0.0  0.0  21312   896 pts/13   R+   14:43   0:00 grep --color=auto ./server
chunli@ubuntu:~$ 

chunli@ubuntu:~$ netstat -apn | grep 8000
(并非所有进程都能被检测到,所有非本用户的进程信息将不会显示,如果想看到所有信息,则必须切换到 root 用户)
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      8368/server     
tcp        0      0 11.11.11.3:8000         11.11.11.3:35222        ESTABLISHED 8376/server     
tcp        0      0 11.11.11.3:35222        11.11.11.3:8000         ESTABLISHED 8375/client     
tcp        0      0 11.11.11.3:8000         11.11.11.8:41417        ESTABLISHED 8384/server     
chunli@ubuntu:~$




---------------------------------------------------

TCP 多线程并发服务器,使用wrap函数封装


TCP 多线程服务器模型,使用wrap函数封装


在使用线程模型开发服务器时需考虑以下问题:


1.调整进程内最大文件描述符上限


2.线程如有共享数据,考虑线程同步


3.服务于客户端线程退出时,退出处理。(退出值,分离态)


4.系统负载,随着链接客户端增加,导致其它线程不能及时得到CPU



 

1,服务端程序 

chunli@ubuntu:~/linux_c/m_pthread$ cat server_pthread.c 
//gcc server_pthread.c wrap.c  -lpthread -Wall
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <ctype.h>
#include "wrap.h"

#define MAXLINE 80
#define SERVER_PORT 8000

struct s_info
{
	struct sockaddr_in cliaddr;	
	int connfd;
};

void *do_work(void *arg)
{
	int n = 0;
	int i = 0;
	struct s_info *ts = (struct s_info*)arg;
	char buf[MAXLINE];
	char str[INET_ADDRSTRLEN];
	/*	在创建线程前设置分离属性比在创建线程后设置分离状态效率高*/
	pthread_detach(pthread_self());	//本示例在线程创建完成后完成自我分离
	while(1)
	{
		n = Read(ts->connfd,buf,MAXLINE);
		if(n == 0)
		{
			printf("the other side has been closed.\n");
			break;
		}
		printf("received from %s at PORT %d\n",
			inet_ntop(AF_INET,&(*ts).cliaddr.sin_addr,str,sizeof(str)),
			ntohs((*ts).cliaddr.sin_port));
		for(i = 0;i < n;i++)
		{
			buf[i] = toupper(buf[i]);
		}
		Write(ts->connfd,buf,n);
	}
	Close(ts->connfd);
	return NULL;	//函数返回值需要返回一个东西
}

int main(void)
{
	struct sockaddr_in serveraddr;
	struct sockaddr_in clientaddr;
	socklen_t cliaddr_len;
	int listenfd = 0;
	int connfd = 0;
	int i = 0;
	pthread_t tid;
	struct s_info ts[383];
	listenfd = Socket(AF_INET,SOCK_STREAM,0);

	bzero(&serveraddr,sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;	//IPV4
	serveraddr.sin_port  =htons(SERVER_PORT);//设置监听端口
	serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);//设置在哪个IP监听
	Bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));	
	Listen(listenfd,20);	//The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow
	printf("Accepting connections....\n");
	while(1)
	{
		cliaddr_len = sizeof(clientaddr);
		connfd = Accept(listenfd,(struct sockaddr*)&clientaddr,&cliaddr_len);
		ts[i].cliaddr = clientaddr;
		ts[i].connfd = connfd;
		/*达到线程最大数时,pthread_create 出错处理,增加服务器的稳定性	*/
		pthread_create(&tid,NULL,do_work,(void*)&ts[i]);
		i++;
	}
	return 0;
}


2,客户端程序:

chunli@ubuntu:~/linux_c/m_pthread$ cat client.c 
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "wrap.h"

#define MAXLINE 80
#define SERVER_PORT 8000
int main(int argc ,char **argv)
{
	struct sockaddr_in serveraddr;
	char buf[MAXLINE];
	int sockfd = 0;
	int n = 0;
	sockfd = Socket(AF_INET,SOCK_STREAM,0);
	bzero(&serveraddr,sizeof(serveraddr));
	serveraddr.sin_family = AF_INET;
	inet_pton(AF_INET,"11.11.11.3",&serveraddr.sin_addr.s_addr);
	serveraddr.sin_port = htons(SERVER_PORT);
	Connect(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
	while(fgets(buf,MAXLINE,stdin) != NULL ) 
	{
		Write(sockfd,buf,strlen(buf));
		n = Read(sockfd,buf,MAXLINE);
		if(n == 0)
		{
			printf("the other side has been close.\n");
		}
		else 
		{
			Write(STDOUT_FILENO,buf,n);
		}
	}
	Close(sockfd);
	return 0;
}



依赖的wrap库源代码

chunli@ubuntu:~/linux_c/m_pthread$ cat wrap.h 
/* wrap.h */
#ifndef __WRAP_H_
#define __WRAP_H_
void perr_exit(const char *s);
int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr);
void Bind(int fd, const struct sockaddr *sa, socklen_t salen);
void Connect(int fd, const struct sockaddr *sa, socklen_t salen);
void Listen(int fd, int backlog);
int Socket(int family, int type, int protocol);
ssize_t Read(int fd, void *ptr, size_t nbytes);
ssize_t Write(int fd, const void *ptr, size_t nbytes);
void Close(int fd);
ssize_t Readn(int fd, void *vptr, size_t n);
ssize_t Writen(int fd, const void *vptr, size_t n);
ssize_t my_read(int fd, char *ptr);
ssize_t Readline(int fd, void *vptr, size_t maxlen);
#endif



chunli@ubuntu:~/linux_c/m_pthread$ cat wrap.c
/* wrap.c */
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
void perr_exit(const char *s)
{
	perror(s);
	exit(1);
}
int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)
{
	int n;
again:
	if ( (n = accept(fd, sa, salenptr)) < 0) {
		if ((errno == ECONNABORTED) || (errno == EINTR))
			goto again;
		else
			perr_exit("accept error");
	}
	return n;
}
void Bind(int fd, const struct sockaddr *sa, socklen_t salen)
{
	if (bind(fd, sa, salen) < 0)
		perr_exit("bind error");
}
void Connect(int fd, const struct sockaddr *sa, socklen_t salen)
{
	if (connect(fd, sa, salen) < 0)
		perr_exit("connect error");
}
void Listen(int fd, int backlog)
{
	if (listen(fd, backlog) < 0)
		perr_exit("listen error");
}
int Socket(int family, int type, int protocol)
{
	int n;
	if ( (n = socket(family, type, protocol)) < 0)
		perr_exit("socket error");
	return n;
}
ssize_t Read(int fd, void *ptr, size_t nbytes)
{
	ssize_t n;
again:
	if ( (n = read(fd, ptr, nbytes)) == -1) {
		if (errno == EINTR)
			goto again;
		else
			return -1;
	}
	return n;
}
ssize_t Write(int fd, const void *ptr, size_t nbytes)
{
	ssize_t n;
again:
	if ( (n = write(fd, ptr, nbytes)) == -1) {
		if (errno == EINTR)
			goto again;
		else
			return -1;
	}
	return n;
}
void Close(int fd)
{
	if (close(fd) == -1)
		perr_exit("close error");
}
ssize_t Readn(int fd, void *vptr, size_t n)
{
	size_t nleft;
	ssize_t nread;
	char *ptr;
	ptr = vptr;
	nleft = n;
	while (nleft > 0) {
		if ( (nread = read(fd, ptr, nleft)) < 0) {
			if (errno == EINTR)
				nread = 0;
			else
				return -1;
		} else if (nread == 0)
			break;
		nleft -= nread;
		ptr += nread;
	}
	return n - nleft;
}
ssize_t Writen(int fd, const void *vptr, size_t n)
{
	size_t nleft;
	ssize_t nwritten;
	const char *ptr;
	ptr = vptr;
	nleft = n;
	while (nleft > 0) {
		if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
			if (nwritten < 0 && errno == EINTR)

				nwritten = 0;
			else
				return -1;
		}
		nleft -= nwritten;
		ptr += nwritten;
	}
	return n;
}
static ssize_t my_read(int fd, char *ptr)
{
	static int read_cnt;
	static char *read_ptr;
	static char read_buf[100];
	if (read_cnt <= 0) {
again:
		if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {
			if (errno == EINTR)
				goto again;
			return -1;
		} else if (read_cnt == 0)
			return 0;
		read_ptr = read_buf;
	}
	read_cnt--;
	*ptr = *read_ptr++;
	return 1;
}
ssize_t Readline(int fd, void *vptr, size_t maxlen)
{
	ssize_t n, rc;
	char c, *ptr;
	ptr = vptr;
	for (n = 1; n < maxlen; n++) {
		if ( (rc = my_read(fd, &c)) == 1) {
			*ptr++ = c;
			if (c == ‘\n‘)
				break;
		} else if (rc == 0) {
			*ptr = 0;
			return n - 1;
		} else
			return -1;
	}
	*ptr = 0;
	return n;
}





服务端编译运行:

chunli@ubuntu:~/linux_c/m_pthread$ gcc server_pthread.c wrap.c  -lpthread -Wall -o server && ./server 
Accepting connections....



服务端查看端口监听:

chunli@ubuntu:~/linux_c/m_fork$ netstat -tnlp
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.1.1:53            0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      9047/server     
tcp6       0      0 :::22                   :::*                    LISTEN      -


客户端1编译运行:

chunli@ubuntu:~/linux_c/m_pthread$ gcc -Wall -o client client.c wrap.c && ./client 
haha
HAHA
English
ENGLISH
hehe   
HEHE


客户端2编译运行:

客户端2编译运行:
chunli@ubuntu14:~/m_pthread$ gcc -Wall -o client client.c wrap.c  && ./client 
ls
LS
hello
HELLO
china
CHINA



服务端输出信息:

chunli@ubuntu:~/linux_c/m_pthread$ gcc server_pthread.c wrap.c  -lpthread -Wall -o server && ./server 
Accepting connections....
received from 11.11.11.3 at PORT 35224
received from 11.11.11.8 at PORT 41418
received from 11.11.11.8 at PORT 41418
received from 11.11.11.8 at PORT 41418
received from 11.11.11.3 at PORT 35224
received from 11.11.11.3 at PORT 35224


服务端线程信息

chunli@ubuntu:~/linux_c/m_fork$ ps -eLf | grep server
chunli     9047   8294   9047  0    3 17:18 pts/13   00:00:00 ./server
chunli     9047   8294   9085  0    3 17:20 pts/13   00:00:00 ./server
chunli     9047   8294   9099  0    3 17:22 pts/13   00:00:00 ./server



服务器线程与客户端连接关系:

chunli@ubuntu:~/linux_c/m_fork$ netstat -anp | grep 8000
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      9047/server     
tcp        0      0 11.11.11.3:8000         11.11.11.3:35224        ESTABLISHED 9047/server     
tcp        0      0 11.11.11.3:8000         11.11.11.8:41418        ESTABLISHED 9047/server     
tcp        0      0 11.11.11.3:35224        11.11.11.3:8000         ESTABLISHED 9084/client     
chunli@ubuntu:~/linux_c/m_fork$


ctrl+c 关闭一个客户端 看看服务端信息输出:

chunli@ubuntu:~/linux_c/m_pthread$ gcc server_pthread.c wrap.c  -lpthread -Wall -o server && ./server 
Accepting connections....
received from 11.11.11.3 at PORT 35224
received from 11.11.11.8 at PORT 41418
received from 11.11.11.8 at PORT 41418
received from 11.11.11.8 at PORT 41418
received from 11.11.11.3 at PORT 35224
received from 11.11.11.3 at PORT 35224
the other side has been closed.


再看服务端线程信息

chunli@ubuntu:~/linux_c/m_fork$ ps -eLf | grep server
chunli     9047   8294   9047  0    2 17:18 pts/13   00:00:00 ./server
chunli     9047   8294   9085  0    2 17:20 pts/13   00:00:00 ./server


把服务端ctrl+c终止运行,再看看剩下的一个客户端输出信息

chunli@ubuntu:~/linux_c/m_pthread$ gcc -Wall -o client client.c wrap.c && ./client 
haha
HAHA
English
ENGLISH
hehe   
HEHE

the other side has been close.




---------------------------------------------


作业:


1.编写获取网络服务器时钟服务器/客户机程序。


2.实现网络版本聊天室服务器客户机

          


本文出自 “魂斗罗” 博客,谢绝转载!

Linux统系统开发11 Socket API编程2 多进程 多线程 高并发处理

标签:linux统系统开发11 socket api编程2 多进程 多线程 高并发处理

原文地址:http://990487026.blog.51cto.com/10133282/1840391

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!