30网络通信之多线程
使用原始的Socket模式,会发生阻塞问题,只能收一条消息再发一条消息。无法做到发送多次消息。
在服务器端创建多线程,每当accept()接受到一个客户端时,启动一条线程单独去处理。

代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<pthread.h>
#define SRV_PORT 0xabcd
#define CLT_PORT 0xaaaa
void *Comm_thread(void *param)
{
int fd = *(int*)param;
int iRet;
char szBuf[1024];
char szMsg[] = "I Received!";
while(1)
{
memset(szBuf, 0, 1024);
iRet = read(fd, szBuf, 1024);
if (iRet < 0)
{
perror("Recv failed!");
break;
}
if (iRet == 0)
{
printf("Disconnect!\n");
break;
}
else
{
printf("Recv:%s\n", szBuf);
//write(fd, szMsg, sizeof(szMsg));
}
}
close(fd);
return NULL;
}
void Tcp_server()
{
int fd;
int iRet;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
fd = socket(PF_INET, SOCK_STREAM, 0);//IPPROTO_IP
if (fd < 0)
{
perror("Socket failed!");
return;
}
addr.sin_family = AF_INET;//use IPV4 address
addr.sin_port = htons(SRV_PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY=0L;
iRet = bind(fd, (struct sockaddr*)&addr, addrlen);
if (iRet)
{
perror("Bind failed!");
close(fd);
return;
}
iRet = listen(fd, 10);
if (iRet)
{
perror("Listen failed!");
close(fd);
return;
}
int clientfd;
struct sockaddr_in srcaddr;
char szTip[] = "Welcome!";
//char szBuf[1024]={};
while(1)
{
clientfd = accept(fd, (struct sockaddr*)&srcaddr, &addrlen);
if (clientfd < 0)
{
perror("Accept failed!");
break;
}
printf("Connect form %s[%d]\n", inet_ntoa(srcaddr.sin_addr), ntohs(srcaddr.sin_port));
//send(clientfd, szTip, strlen(szTip), 0);
write(clientfd, szTip, strlen(szTip)); //send data to client
pthread_t tid;
pthread_create(&tid, NULL, Comm_thread, (void*)&clientfd);
}
close(fd);
return ;
}
void Tcp_client()
{
char szDestIp[16];
int port;
fprintf(stderr, "Connect to:");
scanf("%s%d", szDestIp, &port);
int fd;
int iRet;
struct sockaddr_in srvaddr;
socklen_t addrlen = sizeof(srvaddr);
fd = socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0)
{
perror("Socket failed!");
return;
}
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons((short)port);
srvaddr.sin_addr.s_addr = inet_addr(szDestIp);
iRet = connect(fd, (struct sockaddr*)&srvaddr, addrlen);
if (iRet)
{
perror("Connect failed!");
return;
}
char szBuf[1024];
char szMsg[100];
while(1)
{
memset(szBuf, 0, 1024);
iRet = read(fd, szBuf, 1024);//receive message
if (iRet < 0)
{
perror("Read failed!");
break;
}
if (iRet == 0)
{
printf("Server disconnected\n");
}
printf("Recv: %s\n", szBuf);
fprintf(stderr, "Send:");
memset(szMsg, 0, 100);
read(STDIN_FILENO, szMsg, 100);//get message
write(fd, szMsg, strlen(szMsg)); //send message
}
}
int main(int argc, char** argv)
{
if (argc!=2
|| (strcmp(argv[1], "s") && strcmp(argv[1], "c") )
)
{
printf("Usage: %s [ c | s ]\n", argv[0]);
printf("\t c : For start tcp client\n");
printf("\t s : For start tcp server\n");
return 0;
}
if (argv[1][0] == 's')
{
Tcp_server();
}
else if (argv[1][0] == 'c')
{
Tcp_client();
}
return 0;
}

浙公网安备 33010602011771号