理工大嵌入式操作系统实验报告之网络编程—设计并发服务器

知识共享许可协议 版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

一、实验目的和要求
1 了解TCP/IP协议
2 掌握Socket编程,熟悉基于TCP和UDP的传输模型
3 掌握多线程编程
4 掌握基于TCP的并发服务器设计
二、实验内容和原理
实验内容:编写C程序,利用多线程构建TCP并发服务器,并实现客户端和服务器的传输(多个并发用户同时访问服务器)
实验原理:TCP的传输模型和线程的并发执行
三、主要仪器设备
PC机、装有Linux操作系统的虚拟机
四、操作方法与实验步骤
线程并发客户端:

#include <netinet/in. h>  // for sockaddr_ in
#include <sys/types. h>  // for socket
#include <sys/ socket. h>  // for socket
#include <stdio. h>  // for printf :
#include <stdlib. h>  . // for exit
#include <string. h>  // for bzero
#include <pthread. h>
#include <sys/errno. h>  // for errno
#define HELLO_WORLD_SERVER_PORT  6666
#define BUFFER_SIZE 1024
char * server_IP = NULL;

void * talk_to_server(void * thread_num)
{
	struct sockaddr_in c1ient_addr ;
    bzero (&c1ient_addr, sizeof (c1ient_addr)); //把一段内存区的内容全部没置カ0
	client_addr.sin_family = AF_INET;  //internet
    client_addr.sin_addr.s_addr = htons (INADDR_ ANY);//INADDR_ ANY表示自劫荻取本机地址
    c1ient_addr.sin_port = htons(0) ; 
	int client_socket = socket (AF_INET, SoCK_STREAMI, 0);
	if( c1ient_socket<O)
	{
      printf ("Create Socket Failed!\n");
	  exit(1);
	}
    //把客戸机的socket和客戸机的socket地址結枸朕系起来
    
	if(  bind(c1ient_socket, (structsockaddr*)&client_addr, sizeof(c1ient_addr)))
    {
	printf("C1ient Bind Port Failed!\n");
	exit(1);
	}
    //没置一-个socket地址結枸server_ addr, 代表服努器的internet地址,端ロ
	struct sockaddr_in server_addr ;
    bzero (&server_addr, sizeof (server_addr));
	server_addr.sin_fami1y = AF_INET:
	if(inet_aton (server_IP, &server_addr.sin_addr) == 0) //服务器的IP地址来自程序的参数
    {
	  printf("Server IP Address Error!\n");
	  exit(1);
	}
	  
    server_addr.sin_port = htons (HELLO_WORLD_SERVER_P0RT);
	sock1en_t server_addr_length = sizeof (server_addr);

    if (connect (client_socket,(struct  sockaddr* )&server_addr,server_addr_length) < 0)
    {
      printf("Can Not Connect To %s!\n" ,server_IP);
	  exit(1);
	}
      
	char buffer [BUFFER_SIZE];
	bzero (buffer, BUFFER_SIZE),//从服务器接收数据到buffer中
    int length =recv (client_socket, buffer, BUFFER_SIZE, 0);
    if(length<0)
    {
    	printf("Recieve Data From Server %s Failed!\n");
    	exit(1);
	}
	printf("From Server %s :\t%s",server_IP,buffer);
	bzero(buffer,BUFFER_SIZE);
	sprintf(buffer,"Hello,world! From Client Thread NUM :\t %d\n",(int)thread_num);
	send(client_socket,buffer,BUFFER_SIZE,0);
	close(client_socket);
	pthread_exit(NULL);
}

int main(int argc,char **argv)
{
	
    if (argc != 2)
    {  
	   	printf("Usage: . /%s ServerIPAddress\n" , argv[0]);
	   	exit(1) ;
	}
    server_IP = argv[1];
    pthread_t child_thread;
    pthread_attr_t child_thread_attr;
    pthread_attr_init(&child_thread_attr);
    pthread_attr_setdetachstate (&child_thread_attr, PTHREAD_CREATE_DETACHED);
	int i=0;
    for(i=0; i<10000; i++){
      if(pthread_ create(&child_ thread, &child_thread_attr, talk_to_server, (void *)i)< 0 )
      printf(" pthread_ create Failed : %s\n", strerror (errno)) ;
	}
	return 0;
}

线程并发服务器

#include <netinet/in.h>  // for sockaddr_ in
#include <sys/types.h>  // for socket
#include <sys/socket.h>  // for socket
#include <stdio.h>  // for printf :
#include <stdlib.h>  . // for exit
#include <string.h>  // for bzero
#include <pthread.h>
#include <sys/errno.h>  // for errno
#define HELLO_WORLD_SERVER_PORT  6666
#define LENGTH_OF_LISTEN_QUEUE 20
#define THREAD_MAX 5 
#define BUFFER_SIZE 1024

void * talk_to_client(void *data)
{
	int new_server_socket = (int) data;
	char buffer[BUFFER_SIZE];
	bzero(buffer, BUFFER_SIZE);
    strcpy(buffer, "He11o, World!从服努器来!");
	strcat(buffer,"\n"); 
    send(new_server_socket, buffer, BUFFER _SIZE, 0);
    bzero (buffer , BUFFR_SIZE):

    int length = recv (new_server_socket, buffer, BUFFER_SIZE, 0);
	if (length <0){
      printf(" Server Recieve Data Failed!\n");
	  exit(1);}
    printf(" \nSocket Num: %d \t %s", new_server_socket, buffer);	
    close(new_server_socket) ;
	pthread_exit (NULL);
} 

int main(int argc.char **argv)
{
	struct sockaddr_in server_addr;
	bzero(&server_addr,sizeof(server_addr));
	server_addr.sin_family=AF_INET;
	server_addr.sin_addr.s=htons(INADDR_ANY);
	server_addr.sin_port=htons(HELLO_WORLD_SERVER_PORT);
	int server_socket=socket(AF_INET,SOCK_STREAM,0);
	if(server_socket<0)
	{
		printf("Create Socket Failed!");
		exit(1);
	}
	if(bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)))
	{
		printf("Server Bind Port: %d Failed!",HELLO_WORLD_SERVER_PORT);
		exit(1);
	}
	if(listen(server_socket,LENGTH_OF_LISTEN_QUEUE))
	{
		printf("Server Listen Failed!");
		exit(1);
	}
	while(1)
	{
		struct sockaddr_ in c1ient_addr :
	    socklen_t length = sizeof (c1ient_addr) ;
	    int  new_server_socket=accept (server_socket, (struct sockaddr*)&c1ient_addr , &length);
		if ( new_server_socket<O)
		{
		    printf(" Server Accept Failed!\n");
			break:
		}
	    pthread_t chi1d_thread;
	    pthread_attr_t chi1d_thread_attr ;
	    pthread_attr_init(&chi1d_thread_attr);
	    pthread_attr_setdetachstate (&chi1d_thread_attr, PTHREAD_CREATE_DETACHED);
	    if( pthread_create (&chi1d_thread, &chi1d_thread_attr, talk_to_c1ient,(void *)new_server_socket) <0 )
	    printf("pthread_create Failed : %s\n", strerror (errno));
		  
	}
	close(server_socket);
	return 0;
}

五、实验数据和记录
服务器程序的编译
gcc thread_server1.c -1pthread –o thread_server1
客户端程序编译
gcc thread_client1.c -1pthread –o thread_client1
服务器程序合客户端应当分别在2个终端上。
服务器端程序的运行,在一个终端执行
./thread_server1
客户端程序在另一个终端执行
./thread_client1 127.0.0.1

猜你喜欢

转载自blog.csdn.net/weixin_44611644/article/details/95069098