经过多次尝试,终于测试成功linux环境下TCP/IP的多线程通信,与网上大多数代码的区别在于,网上的很多代码都是把发送或者接收的功能之一放在主线程中,这样就导致如果要在主线程撰写一些具体的操作就会造成卡死,或者响应不及时。查阅了资料,用了合适的方法把接收和发送分离在两个子线程。难点在于退出的时候如何结束线程,方法是在发送的线程里,接收到结束命令时,先把接收的线程结束掉pthread_cancle(),再自己结束掉线程pthread_exit(),然后在主线程里面通过pthread_join()等待子线程结束的命令,运行效果良好,现分享给大家。注意,服务器这里的接收和发送其中一个功能仍然在主线程里面,因为本人在服务器的操作命令不多,所以没有加以修改,如果有人需要服务器进行多种操作,也可以仿照client.cpp的形式修改,欢迎留言讨论。
client.cpp
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h> //atoi()
#include <pthread.h>
#include <string>
#include <vector>
#include <iostream>
using std::string;
using std::cout;
static pthread_t send_thread;
//客户端的发送功能要放在子线程里面
void * recv_msg(void *arg);//接收消息函数声明
void * send_msg(void *arg);
std::vector<std::string> split(std::string str, std::string pattern);
struct myData
{
float x[10];
float y[10];
float z[10];
float w[10];
};
static struct myData mData;
int main(int argc, char *argv[])
{
//判断参数个数是否匹配
int port = 7777;//从命令行接收参数
if( port<1025 || port>65535 )//0~1024一般给系统使用,一共可以分配到65535
{
printf("端口号范围应为1025~65535");
return -1;
}
//1 创建tcp通信socket
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if(socket_fd == -1)
{
perror("socket failed!\n");
}
//2 连接服务器
struct sockaddr_in server_addr = {0};//服务器的地址信息
server_addr.sin_family = AF_INET;//IPv4协议
server_addr.sin_port = htons(port);//服务器端口号
server_addr.sin_addr.s_addr = inet_addr("10.40.128.128");//设置服务器IP
int ret = connect(socket_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if(ret == -1)
{
perror("connect failed!\n");
}
else
{
printf("connect server successful!\n");
}
//开启接收线程
pthread_t recv_thread;//存放线程id recv_msg:线程执行的函数,将通信socket:new_socket_fd传递进去
ret = pthread_create