您的位置:首页 > 运维架构 > Linux

2.3 linux实现服务端与多个客户端间通讯-线程Socket-pthread的方法(实验一)

2018-01-19 17:10 671 查看
                                                    实验一              线程Socket-pthread的方法

-------------------下面代码来源于网上,本人仅测试和修改,并未做其他改变

     在测试过程中发现,记录如下:

1.客户端1发消息,服务器将收到的消息只转发给客户端1,并不会转发给客户端2(正常)
2.客户端不能给服务器发消息,只有服务器可以发消息(待优化)
============================================================================
                                                                                             代码如下

                                         功能:多个客户端给服务器发消息,服务器把接收到的数据打印出来后,把数据又发回客户端

============================================================================

第一部分

服务器端代码 如下:

//server_pthread.c
//利用多线程处理多路复用的问题
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include "stdio.h"
#include "pthread.h"
#include "stdlib.h"
#include <errno.h>

// 利用多线程
struct sockaddr_in addrSrv,addrClt;
int socketSrv;
void f1(int *socketCtl2)//利用pthread_create把参数传进来
{
char buf[1024],buf2[1024];
int len;
memset(buf,0,1024);
memset(buf2,0,1024);
while(1)
{
printf("\n*socketCtl2==%d\n",*socketCtl2);
//接收客户传过来的信息
len=recv(*socketCtl2,buf,1024,0);
if(len==0)
{
printf("one client over\n");
close(*socketCtl2);
pthread_exit(NULL);
//return;
}

if(len<0) perror("recv error");
buf[len]=0;
if(strncmp(buf,"end",3)==0)
{
close(*socketCtl2);
pthread_exit(NULL);
//break;
};
//把接收到的数据打印出来
printf("recv msg : %s",buf);
//sprintf(buf2,"server dispatcmsg:%s",buf);

//把数据又发回客户端
if(send(*socketCtl2,buf,len,0)<0)
{
perror("send");
printf("\nerrno==%d\n",errno);
}

}
}

int main()
{
int len;
int socketClt;
socketSrv=socket(AF_INET,SOCK_STREAM,0);

addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(8002);
addrSrv.sin_addr.s_addr=htonl(INADDR_ANY);
memset(addrSrv.sin_zero,0,8);

if(bind(socketSrv,(struct sockaddr*)
b825
&addrSrv,sizeof(addrSrv))<0) perror("bind");
listen(socketSrv,100);
len=sizeof(addrClt);
while(1)
{
pthread_t pid;
//主线程每收到一个连接请求,就创建一个子线程与之对应连接
int socketCtl= accept(socketSrv,(struct sockaddr*)&addrClt,(socklen_t*)(&len));  //返回一个小socketCtl号

int *temp=(int *)malloc(sizeof(int)); //防止socketCtl被覆盖,所以每次都新开一个空间来存放
*temp=socketCtl;  //由于多个线程共享 socketctrl 所以每次都要重新分配空间
//把socketCtl 传给子线程处理
pthread_create(&pid,NULL,(void *)f1,temp);//一个线程处理一个客户端
}
close(socketClt);
close(socketSrv);
return 0;
}


==================================================================================================

第二部分

客户端代码 如下:

//client_pthread.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
int main()
{
char buf[1024],buf2[1024];
int len,flags;
int socketSrv= socket(AF_INET,SOCK_STREAM,0);

struct sockaddr_in addrSrv;
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(8002);
addrSrv.sin_addr.s_addr=inet_addr("47.92.68.40");
memset(addrSrv.sin_zero,0,8);
len=sizeof(addrSrv);

connect(socketSrv,(struct sockaddr *)&addrSrv,(socklen_t)len);

while(1)
{
memset(buf,0,1024);
memset(buf2,0,1024);
puts("please input something");
gets(buf);
if(strncmp(buf,"end",3)==0) break;
if(send(socketSrv,buf,strlen(buf),0)==-1)
{
perror("send");
printf("before errno=%d\n",errno);
}
if(recv(socketSrv,buf2,1024,0)==-1)
{
perror("recv");
printf("errno=%d\n",errno);
}
puts(buf2);
}
close(socketSrv);
return 0;

}

 ================================================================================================

流程和现象如下:
 
          实验测试采用了2个客户端(一个虚拟机,一个网络调试助手软件)同时连接一个服务端(阿里云服务器)进行测试。

1.服务器端Socket开启:

    服务器端(命令行操作)      -->

    [root@iZ8vbaavwnqazypjccdk21Z socket_pthread]# ./tcpserver

2.客户端1 Socket开启:

    客户终端1(虚拟机)    -->

    ql@ql-virtual-machine:/mnt/hgfs/GitHub/socket_pthread_test$ ./tcpclient 
3.服务器端现象:
   服务器端 (命令行现象)     -->

   *socketCtl2==4                                            ------提示客户端1上线且为4号线程
4.客户端2 Socket开启:

  客户终端2(网络调试助手软件)   -->
  TCP Client     47.92.68.40   8002

5.服务器端现象:

  服务器端(命令行现象)
     -->

  *socketCtl2==5                                            -------提示客户端2上线且为5号线程
6.客户端1 给 服务器发消息helloworld:

  客户终端1(虚拟机)    -->
   please input something

   helloworld                                                   --------这是客户端1命令行  打的helloworld 

   helloworld                                                   --------这是服务器 把数据又发回客户端
 7.服务器端现象:

  服务器端      -->

  recv msg : helloworld
  *socketCtl2==4
8.客户端2 给 服务器发消息78910 :

  客户终端2(网络调试助手)   -->

  78910
9.服务器端现象:
  服务器端      --> 

  recv msg : 78910

  *socketCtl2==5
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐