先看几个基本概念:
线程ID:
//头文件
#include
pthread_t ;
typedef unsigned long int pthread_t;
线程属性:
pthread_attr_t ;
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
创建线程:
int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, (void*)(*start_rtn)(void*), void *arg);
//pthread_t *tidp 线程ID
//const pthread_attr_t *attr 线程属性
//(void*)(*start_rtn)(void*) 函数指针,处理函数
//void *arg 处理函数的参数
服务端示例代码:
#include
#include
#include
#include
#include
#include
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVER_PORT_TCP 6666
#define TCP_BACKLOG 10
/* 在sock_fd 进行监听,在 new_fd 接收新的链接 */
int sock_fd, new_fd;
void printf_hex(char *buf, int len)
{
int i;
for(i = 0; i < len; i++)
{
printf("0x%x ", buf[i]);
}
}
void sig_chld(int signo)
{
pid_t pid;
int stat;
while((pid = waitpid(-1, &stat, WNOHANG)) > 0)
printf("child %d terminated\r\n", pid);
return;
}
void *__tcp_server(void *pdata)
{
int new_socket = pdata;
//处理目标
ssize_t ret;
char recvbuf[512];
char *buf = "hello! I'm server!";
while(1)
{
if((ret = recv(new_socket, recvbuf, sizeof(recvbuf), 0)) == -1){
printf("recv error \r\n");
return -1;
}
printf("recv :\r\n");
printf("%s", recvbuf);
printf("\r\n");
sleep(2);
if((ret = send(new_socket, buf, strlen(buf) + 1, 0)) == -1)
{
perror("send : ");
}
}
close(new_socket);
}
int main(void)
{
char command[1024];
char *str;
/* 自己的地址信息 */
struct sockaddr_in my_addr;
/* 连接者的地址信息*/
struct sockaddr_in their_addr;
int sin_size;
struct sockaddr_in *cli_addr;
/* 1 、创建socket */
if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket is error\r\n");
exit(1);
}
/* 主机字节顺序 */
/* 协议 */
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(6666);
/* 当前IP 地址写入 */
my_addr.sin_addr.s_addr = INADDR_ANY;
/* 将结构体其余的都清零 */
bzero(&(my_addr.sin_zero), 8);
/* bind 绑定*/
if(bind(sock_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
{
perror("bind is error\r\n");
exit(1);
}
/* 开始监听 */
if(listen(sock_fd, TCP_BACKLOG) == -1)
{
perror("listen is error\r\n");
exit(1);
}
printf("start accept\n");
/* 因为我们后面会创建出许多子进程来服务新的链接
一旦子进程异常终止了,需要父进程来进行资源回收
*/
signal(SIGCHLD, sig_chld); //在这里处理僵死进程
/* accept() 循环 */
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if((new_fd = accept(sock_fd, (struct sockaddr *)&their_addr, (socklen_t *)&sin_size)) == -1)
{
perror("accept");
continue;
}
pthread_t server_thread;
pthread_attr_t server_thread_attr;
/* 创建子进程 */
pthread_attr_init(&server_thread_attr); //初始化进程属性
pthread_attr_setdetachstate(&server_thread_attr, PTHREAD_CREATE_DETACHED);
// if (pthread_create(&recv_thread, &recv_thread_attr, recv_pthread, NULL) < 0)
if (pthread_create(&server_thread, &server_thread_attr, __tcp_server, new_fd) < 0)
{
perror("pthread_create");
}
}
return 0;
}
客户端示例代码:
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int sockfd;
//#define SERVER_IP "106.13.62.194"
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 6666
void printf_hex(char *buf, int len)
{
int i;
for(i = 0; i < len; i++)
{
printf("0x%x ", buf[i]);
}
}
char *device_id ;
int main(int argc,char **argv)
{
char command[1024];
char *str;
/* 连接者的主机信息 */
struct sockaddr_in their_addr;
if(argc != 2)
{
printf("pls input devide id\r\n");
return 0;
}
device_id = (argv[1]);
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
/* 如果socket()调用出现错误则显示错误信息并退出 */
perror("socket");
// exit(1);
}
/* 主机字节顺序 */
their_addr.sin_family = AF_INET;
/* 网络字节顺序,短整型 */
their_addr.sin_port = htons(SERVER_PORT);
their_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
/* 将结构剩下的部分清零*/
bzero(&(their_addr.sin_zero), 8);
if(connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1)
{
/* 如果connect()建立连接错误,则显示出错误信息,退出 */
perror("connect");
exit(1);
}
ssize_t ret;
char recvbuf[512];
char buf[1024];
sprintf(buf, "hello, I'm %s", device_id);
while(1)
{
if((ret = send(sockfd, buf, strlen(buf) + 1, 0)) == -1)
{
perror("send : ");
}
sleep(2);
if((ret = recv(sockfd, &recvbuf, sizeof(recvbuf), 0)) == -1){
return -1;
}
printf("recv :\r\n");
printf("%s", recvbuf);
printf("\r\n");
sleep(2);
}
close(sockfd);
return 0;
}
参考资料: