您的位置:首页 > 理论基础 > 计算机网络

一个简单的tcp client/server小程序

2012-11-14 22:10 543 查看
下面是一个tcp小程序:

先来看看在linux下运行的效果截图:

client:运行的截图



server
运行的截图



下面是这两个程序

server.c

#include<stdio.h>

#include<sys/socket.h>

#include<arpa/inet.h>

#include<errno.h>

#include<stdlib.h>

#include<strings.h>

#include<string.h>

#define TRY_TIME 128

#define MAX_CONNECT 12

#define BUFFER_SIZE 1024

//端口

#define SERPORT 2222

void printerr()

{

fprintf(stderr,"server error %s",strerror(errno));

}

int main(int argc,char *argv){

struct sockaddr_in serv;

struct sockaddr_in client;

char addr[INET_ADDRSTRLEN];

int fd;

char buf[BUFFER_SIZE];

int accept_fd;

int reuse=1;

int len=sizeof(struct sockaddr_in);

bzero(&serv,sizeof(struct sockaddr_in));

serv.sin_family=AF_INET;

serv.sin_addr.s_addr=htonl(INADDR_ANY);

serv.sin_port=htons(SERPORT);

//创建一个socket;

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

{

printf("socket");

printerr();

return -1;

}

if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(int))<0)

{

printerr();

return -1;

}

//绑定

if(bind(fd,(struct sockaddr *)&serv,sizeof(struct sockaddr)))

{

printf("bind");

printerr();

return -1;

}

//监听

if(listen(fd,MAX_CONNECT)){

printf("listen");

printerr();

return -1;

}

//不断地接受连接

while(1){

bzero(buf,BUFFER_SIZE);

if((accept_fd=accept(fd,(struct sockaddr *)&client,&len))<0)

{

printerr();

return -1;

}

inet_ntop(AF_INET,&client.sin_addr,addr,INET_ADDRSTRLEN);

printf("accept from %s\n",addr);

recv(accept_fd,buf,BUFFER_SIZE,0);

printf("%s\n",buf);

close(accept_fd);

}

close(fd);

return 0;

}

client.c程序代码如下:

#include<stdio.h>

#include<sys/socket.h>

#include<arpa/inet.h>

#include<errno.h>

#include<stdlib.h>

#include<strings.h>

#include<string.h>

#define TRY_TIME 128

#define BUFFER_SIZE 1024

//端口

#define SERPORT 2222

//如果连接失败返回-1,成功返回0

int connect_retry(int fd,struct sockaddr *addr,socklen_t len){

int i;

for(i=1;i<TRY_TIME;i *=2){

//==0表示连接成功了

if(connect(fd,addr,len)==0)

{

return 0;

}

if(i<TRY_TIME/2)

{

sleep(i);

}

}

return -1;

}

//出错提示

void printerr(char *serv_ip)

{

fprintf(stderr,"can't connect to %s:%s",serv_ip,strerror(errno));

}

int main(int argc,char **argv){

int fd;

struct sockaddr_in ser_ip;

in_addr_t ip;

char buf[BUFFER_SIZE];

//把字符串地址转换成数字地址

//这里的地址解析方法有几种

if(argc !=2)

{

printf("error argc\n");

return -1;

}

if(inet_pton(AF_INET,argv[1],&ip)!=1)

{

printf("error inet_pton");

return -1;

}

//首先清零

bzero(&ser_ip,sizeof(struct sockaddr_in));

//设置

ser_ip.sin_family=AF_INET;

ser_ip.sin_addr.s_addr=ip;

ser_ip.sin_port=htons(SERPORT);

//创建一个socket

if((fd=socket(AF_INET,SOCK_STREAM,0))<0){

printerr(argv[1]);

return -1;

}

//建立连接

if(connect_retry(fd,(struct sockaddr *)&ser_ip,sizeof(struct sockaddr)))

{

printerr(argv[1]);

return -1;

}

printf("send msg:");

fgets(buf,BUFFER_SIZE,stdin);

//发送消息

if(send(fd,buf,strlen(buf),0)==-1)

{

printerr(argv[1]);

return -1;

}

close(fd);

}

程序没有什么特别的,但是要注意2个小的地方:

1:代码如下

if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(int))<0)

{

printerr();

return -1;

}

如果没有这个设置的话,server.c重新运行的时候会报不能重新绑定到同一个地址(除非过了一段时间之后);

2:代码如下

int connect_retry(int fd,struct sockaddr *addr,socklen_t len){

int i;

for(i=1;i<TRY_TIME;i *=2){

//==0表示连接成功了

if(connect(fd,addr,len)==0)

{

return 0;

}

if(i<TRY_TIME/2)

{

sleep(i);

}

}

return -1;

}

有时候服务器忙的时候会不能连接,不能连接可能是一瞬间的事,通过上面的代码可以比较好的解决;每次如果不能连接会sleep一段时间,然后重试连接;

上面的代码参考<<apue>>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: