|
在Linux系统中TCP通信十分常见,TCP通信可以发生在同一局域网中或跨局域网的互联网之间的设备。Linux本身就支持基于C语言的TCP/IP协议通信,需要包含以下头文件:
#include
#include
#include
#include
#include
#include
#include
无论是Linux还是别的系统,要进行TCP通信都有几个步骤,在源码中以函数操作简化了,对于TCP服务器初始化,分别是socket()初始化套接字,bind()绑定,listen()监听,accept()接听:
socklen_t addrsize=sizeof(struct sockaddr);
struct sockaddr_in sockaddr_in_comm,sockaddr_in_settings;
//初始化该结构体变量
bzero(&sockaddr_in_settings,sizeof(sockaddr_in_settings));
sockaddr_in_settings.sin_family=AF_INET;
sockaddr_in_settings.sin_addr.s_addr=inet_addr("169.254.122.5");
sockaddr_in_settings.sin_port=htons(8086);
fd_socket=socket(AF_INET,SOCK_STREAM,0);
if(fd_socket==-1)
{
printf("套接字初始化失败!\n");
return -1;
}
ret=bind(fd_socket,(struct sockaddr *)&sockaddr_in_settings,addrsize);
if(ret==-1)
{
printf("套接字绑定失败!\n");
return -1;
}
ret=listen(fd_socket,5);
if(ret==-1)
{
printf("服务器监听失败!\n");
return -1;
}
newsock=accept(fd_socket,(struct sockaddr *)&sockaddr_in_comm,&addrsize);
if(newsock==-1)
{
printf("服务器接听失败!\n");
return -1;
}
当listen和accept操作完成之后,就可以使用recv和send两个函数进行TCP的接收和发送操作了,像上面的代码,开启了IP为169.254.122.5,端口为8086的服务器:
while(1)
{
bzero(recvbuf,100);
recv(newsock,recvbuf,100,0);
printf("客户端发来信息:%s\n",recvbuf);
}
注意recv函数跟scanf一样,是阻塞的,因此Linux要同时进行TCP通信接收发送的话,需要开启多线程,在main函数中使用pthread_create函数,指定函数指针,并在程序的别的地方写一个返回值为void*的函数:
pthread_create(&id1,NULL,Thread_Send_buf,NULL);
void *Thread_Send_buf(void *arg)
{
char sendbuf[100];
while(1)
{
bzero(sendbuf,100);
scanf("%s",sendbuf);
send(newsock,sendbuf,100,0);
}
}
执行程序后,使用SSCOM或者别的软件以客户端身份登录TCP服务器,并发送一些字符串,由于TCP通信传输的单位是八位字节数据,如果在接收端不做GB2312编码判断并解码的话是无法解析中文信息的,因此发送中文会显示乱码:
然后是客户端给服务器回应信息,注意此时的sendbuf数组没有做基于发送信息长度的判断,信息的长度恒定为100,后面会以'\0'填充:
所以我们再做一个不定长发送缓冲判断算法,非常简单:
void *Thread_Send_buf(void *arg)
{
char sendbuf[100];
int len;
while(1)
{
bzero(sendbuf,100);
scanf("%s",sendbuf);
for(len=0;sendbuf[len]!='\0';len++);
send(newsock,sendbuf,len,0);
}
}
看看效果:
|
|