TCP程序设计
下面的一幅图是取自《UNIX网络编程卷一》,这个简单的C/S程序的框架,应该可以一下很容易看懂。
下面是我写的一个例子:
服务端:
/*
tcp_server.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define portnumber 3333
int main(int argc,char * argv[])
{
int sockfd,new_fd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int sin_size;
int nbytes;
char buffer[1024];
//创建sockfd描述符,AF_INET代表IPv4,SOCK_STREAM代表TCP
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
fprintf(stderr,"socket error %s",strerror(errno));
exit(1);
}
//服务器填充sockaddr结构
bzero(&server_addr,sizeof(struct sockaddr_in));//初始化,置0。
server_addr.sin_family = AF_INET;
//将本机器上的long数据转化为网络上的long数据
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//将本机的short数据转化为网络上的short数据
server_addr.sin_port = htons(portnumber);
//捆绑sockfd描述符到IP地址
if (bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr)) == -1)
{
fprintf(stderr,"bind error %s\n\a",strerror(errno));
exit(1);
}
//设置允许的最大客户端连接数
if (listen(sockfd,5) == -1)
{
fprintf(stderr,"listen error %s\n\a",strerror(errno));
exit(1);
}
while(1)
{
//服务器阻塞知道客户程序建立连接
sin_size == sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size)) == -1)
{
fprintf(stderr,"accept error %s\n\a",strerror(errno));
exit(1);
}
fprintf(stderr,"server get connection from %s\n\a",inet_ntoa(client_addr.sin_addr));
if ((nbytes = read(new_fd,buffer,1024)) == -1)
{
fprintf(stderr,"read error %s \a\n",strerror(errno));
exit(1);
}
buffer[nbytes] = '\0';
printf("server received %s\n",buffer);
close(new_fd);
}
exit(0);
}
客户端:
/*
tcp_client.c
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define portnumber 3333
int main(int argc,char *argv[])
{
int sockfd;
char buffer[1024];
struct sockaddr_in server_addr;
struct hostent * host;
if (argc != 2)
{
fprintf(stderr,"Usage: %s hostname\a\n",argv[0]);
exit(1);
}
if ((host = gethostbyname(argv[1])) == NULL)
{
fprintf(stderr,"gethostname error \n\a");
exit(1);
}
//客户端开始建立sockfd描述符
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
fprintf(stderr,"scoket error %s\a\n",strerror(errno));
exit(1);
}
bzero(&server_addr,sizeof(server_addr));//初始化,置0.
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(portnumber);//将本机的short数据转化为网络的short数据
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
//客户程序发起连接请求
if (connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr)) == -1)
{
fprintf(stderr,"connect error %s\a\n",strerror(errno));
exit(1);
}
//连接成功
printf("Please input char:\n");
//发送数据
fgets(buffer,1024,stdin);
write(sockfd,buffer,strlen(buffer));
//结束通讯
close(sockfd);
exit(0)}
tcp_client.c
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define portnumber 3333
int main(int argc,char *argv[])
{
int sockfd;
char buffer[1024];
struct sockaddr_in server_addr;
struct hostent * host;
if (argc != 2)
{
fprintf(stderr,"Usage: %s hostname\a\n",argv[0]);
exit(1);
}
if ((host = gethostbyname(argv[1])) == NULL)
{
fprintf(stderr,"gethostname error \n\a");
exit(1);
}
//客户端开始建立sockfd描述符
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
fprintf(stderr,"scoket error %s\a\n",strerror(errno));
exit(1);
}
bzero(&server_addr,sizeof(server_addr));//初始化,置0.
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(portnumber);//将本机的short数据转化为网络的short数据
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
//客户程序发起连接请求
if (connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr)) == -1)
{
fprintf(stderr,"connect error %s\a\n",strerror(errno));
exit(1);
}
//连接成功
printf("Please input char:\n");
//发送数据
fgets(buffer,1024,stdin);
write(sockfd,buffer,strlen(buffer));
//结束通讯
close(sockfd);
exit(0)}