服务端是一个选代服务端,持续提供服务,同时只能为一个客户端提供服务。
信息传输协议(V2.0):1字节字符串长度+字符串内容(长度小于255)
信息传输协议(V3.0):4字节字符串长度+字符串内容(长度小于2^32)
服务器端:
#include
#include
#include
#include
#include
#include
#define BUF_SIZE 1024
void error_handling(char *message);
int main(int argc, char* argv[]){
int serv_sock, clnt_sock;
char message[BUF_SIZE];
int i,len;
struct sockaddr_in serv_adr, clnt_adr;
socklen_t clnt_adr_sz;
if(argc != 2){
printf("Usage : %s \n" , argv[0]);
exit(1);
}
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if(serv_sock == -1){
error_handling("socket() error!");
}
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_adr.sin_port = htons(atoi(argv[1]));
if(bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == -1){
error_handling("bind() error!");
}
if(listen(serv_sock, 5) == -1){
error_handling("listen() error!");
}
clnt_adr_sz = sizeof(clnt_adr);
for(i = 0; i < 5; i++){
clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);
if(clnt_sock==-1)
error_handling("accept() error!");
else
printf("Connected client %d\n", i + 1);
while(1){
len=0;
read(clnt_sock,&len,1);
read(clnt_sock,message,len);
write(clnt_sock,message,len);
}
close(clnt_sock);
}
close(serv_sock);
return 0;
}
void error_handling(char *message){
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
客户端:
#include
#include
#include
#include
#include
#include
#define BUF_SIZE 1024
void error_handling(char *message);
int main(int argc, char *argv[])
{
int sock;
char message[BUF_SIZE];
char temp[BUF_SIZE];
int str_len;
int len;
struct sockaddr_in serv_adr;
if(argc != 3){
printf("Usage: %s " , argv[0]);
exit(1);
}
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock == -1)
error_handling("socket() error!");
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = inet_addr(argv[1]);
serv_adr.sin_port = htons(atoi(argv[2]));
if(connect(sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == -1)
error_handling("connect() error!");
else
puts("Connected.........");
while(1)
{ printf("请输入字符串长度: ");
scanf("%d",&len);
write(sock,(char*)&len,1);
printf("请输入内容(按Q退出): ");
scanf("%s",temp);
if(!strcmp(temp,"q")||!strcmp(temp,"Q"))
break;
write(sock,temp,len);
read(sock,message,len);
printf("消息为:%s\n",message);
}
close(sock);
return 0;
}
void error_handling(char *message){
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
测试:
首先对服务器端进行执行。打开一个终端,执行下列指令:
编译:gcc echo_server.c -o eserver
执行:./eserver 9190
正常情况下程序将停留在此状态,因为服务器端调用的accept函数还未返回。
接下来运行客户端,打开另一个终端,执行下列指令:
编译:gcc echo_client.c -o eclient
运行:./eclient 127.0.0.1 9190
开始测试,发现当所输入字符串长度大于等于实际长度时,服务器返回给客户端的字符串是正确的,当字符串实际长度大于输入的字符串长度时,只输出之前向服务器输入的字符串长度所对应的字符串。
例如:
长度为7,字符串为hello,服务器返回hello;
长度为7,字符串为helloworld,服务器返回hellowo。