linux下一个简单的TCP通信程序——客户端向服务端发送任意字符串

来源:互联网 发布:书包推荐 知乎 编辑:程序博客网 时间:2024/05/21 00:48

程序目的:服务器端等待客户端连接,若连接成功,则用户可以通过服务器在接受到字符串后进行判断,若不是quit字符串则输出客服端的地址信息,以及接受到的数据,同将接受到的数据按照原样再发给客服端,若是quit字符串则断开本次连接。

问题以及解决:1)服务器端不能连续显示客户端发送的数据2)服务器端发送的数据在客户端正常显示一次,以后乱码。

#include<sys/stat.h>

#include<fcntl.h>

#include<errno>

#include<netdb.h>

#include<sys/types.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<arpa/inet.h>

#include<string.h>

#include<stdlib.h>

#include<stdio.h>

#include<unistd.h>

#define SERVER_PORT 5555

int main()

{

int serverSocket;

struct sockaddr_in server_addr;

struct sockaddr_in clientAddr;

int addr_len = sizeof(clientAddr);

int client;

char buffer[1024];

int iDataNum;

if((serverSocket = socket(AF_INET,SOCK_STREAM,0)) < 0)

{

perror("socket");

exit(1);

}

bzero(&sever_addr,sizeof(server_addr));

server_addr.sin_family = AF_INET;

server_addr.sin_port = htons(SERVER_PORT);

server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

if(bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)

{

perror("connect");

exit(1);

}

if(listen(serverSocket, 5) < 0)

{

perror("listen");

exit(1);

}

while(1)

{

client = accept(serverSocket, (struct sockaddr *)&clientAddr, (socklen_t*)&addr_len);

if(client < 0)

{

perror("accept");

continue;

}

iDataNum = recv(client, buffer, 1024,0);

if(iDataNum < 0)

{

perror(“recv”);

continue;

}

printf("\nRecv client data..n");

printf("IP is %s\n", inet_ntoa(clientAddr.sin_addr));

printf("port is %d\n",htons(clientAddr.sin_port));

printf("recv data is %s\n",buffer);

send(client, buffer, sizeof(buffer),0);

}

return 0;

}


客户端代码:

#include<sys/stat.h>

#include<fcntl.h>

#include<errno>

#include<netdb.h>

#include<sys/types.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<arpa/inet.h>

#include<string.h>

#include<stdlib.h>

#include<stdio.h>

#include<unistd.h>

int main()

{

struct sockaddr_in serverAddr;

int clientSocket;

char sendbuf[200];

char recvbuf[200];

if((clientSocket = socket (AF_INET, SOCK_STREAM,0)) < 0)

{

perror("socket error");

return -1;

}

serverAddr.sin_family = AF_INET;

serverAddr.sin_port = htons(5555);

serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

if(connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0)

{

perror("connect");

exit(1);

}

printf("connect with destination host..\n");

while(1)

{

printf("input your world:>");

scanf("%s", sendbuf);

printf("\n");

if(strcmp(sendbuf,"quit") == 0)

break;

send(clientSocket,sendbuf, sizeof(sendbuf),0);

recv(clientSocket, recvbuf,200,0);

printf("recv data of my world is : %s\n", recvbuf);

}

close(clientSocket);

return 0;

}


对于问题1使用do  while循环do { iDataNum = recv(client, buffer, 1024,0)

if(iDataNum < 0)

{

perror(“recv”);

exit(1);

}

if(iDataNum == 0 )

break;

printf("\nRecv client data..n");

printf("IP is %s\n", inet_ntoa(clientAddr.sin_addr));//函数简介linux下: 函数声明:char *inet_ntoa (struct in_addr); 返回点分十进制的字符串

printf("port is %d\n",htons(clientAddr.sin_port));

printf("recv data is %s\n",buffer);

send(client, buffer, sizeof(buffer),0);

}while(1);

或者while((n =recv(client, buffer,1024, 0)) > 0)

{

}

第二个问题:客服端的问题,就是缓冲区长度问题,对于客户端第一次来说是正常的,服务器发过来1024个字节的数据,而客户端的接受长度只有200,其他的在缓冲区,所以下次服务器再发送数据时候那么客户端得到的就不是这些数据,而是存在缓冲区中的数据,所以会乱码,所以改客户端char recvbuf[200] 为char recvbuf[1024],和服务器端对应起来,同样recv(clientSocket, recvbuf,200,0);改为recv(clientSocket, recvbuf,1024,0);同时为了防止发送接收数据不同,在send发送后sleep(1),再recv比较合理,注意linux和windows下sleep参数不同一个是毫秒一个是秒.或者客户端发送的时候用strlen(buffer)而不是sizeof(buffer)