利用简单的TCPsocket编程,实现服务器端与客户端的通信。
操作系统:Ubuntu 11.10
编辑器:vim
编译器:gcc
服务器端程序:
#include<stdio.h>
#include<sys/socket.h>
#include<errno.h>
#include<netinet/in.h>
#include<string.h>
#define DATA_LEN 1024
/*函数名:main*/
/*功能:套接字服务器端程序*/
int main(int argc,char *argv[])
{
/*调用socket()函数创建套接字,获得文件描述符sock_server*/
int sock_server=socket(AF_INET,SOCK_STREAM,0);//创建套接字,参数AF_INET-IPV4协议,SOCK_STREAM-套接口类型,0-不是原始套接口就写为0
if(sock_server==-1)
{
printf("%s\n",strerror(errno));
return -1;
}
/*调用bind()函数将套接字绑定在指定地址和端口*/
int listen_port=atoi(argv[1]);//可由运行时指定端口
struct sockaddr_in addr_server;//套接字地址结构
addr_server.sin_family=AF_INET;
addr_server.sin_port=htons(listen_port);//将端口号转换成网络字节顺序
addr_server.sin_addr.s_addr=htonl(INADDR_ANY);//将ip地址转换成网络字节顺序
if(bind(sock_server,(struct sockaddr*)&addr_server,sizeof(addr_server))==-1)
{
printf("%s\n",strerror(errno));
return -1;
}
/*调用listen()函数接收连接请求*/
if(listen(sock_server,10)==-1)
{
printf("%s\n",strerror(errno));
return -1;
}
/*调用accept()函数,返回一个已完成的连接*/
struct sockaddr_in addr_client;
int len_addr_client=sizeof(addr_client);
int sock_client=accept(sock_server,(struct sockaddr *)&addr_client,&len_addr_client);//sock_client为返回的套接口描述字
if(sock_client==-1)
{
printf("%s\n",strerror(errno));
return -1;
}
/*调用send()、recv()函数完成发送发送接收数据*/
char buf[DATA_LEN];
int size;
while(1)
{
size=recv(sock_client,buf,DATA_LEN,0);//从客户端接收数据,将数据存入buf,返回数据的大小
buf[size]='\0';//添加字符串结束标记位
printf("%s\n",buf);
// scanf("%s",buf);
gets(buf);
size=send(sock_client,buf,DATA_LEN,0);//写数据到客户端
}
close(sock_server);//关闭连接
close(sock_client);
return 1;
}
客户端程序:
#include<stdio.h>
#include<sys/socket.h>
#include<errno.h>
#include<netinet/in.h>
#include<string.h>
#define DATA_LEN 1024
/*函数名:main*/
/*功能:socket的客户端程序*/
int main(int argc,char *argv[])
{
/*调用socket()函数创建套接字*/
int sock_client=socket(AF_INET,SOCK_STREAM,0);
if(sock_client==-1)
{
printf("%s\n",strerror(errno));
return -1;
}
/*调用connect()函数连接到服务器*/
int connect_port=atoi(argv[2]);
struct sockaddr_in addr_server;
addr_server.sin_family=AF_INET;
addr_server.sin_port=htons(connect_port);
if(inet_pton(AF_INET,argv[1],(void *)&addr_server.sin_addr.s_addr)==0)//将ip地址转换成二进制数值
{
printf("error\n");
return -1;
}
if(connect(sock_client,(struct sockaddr*)&addr_server,sizeof(addr_server))==-1)
{
printf("%s\n",strerror(errno));
return -1;
}
/*调用send()、recv()函数完成发送接收*/
char buf[DATA_LEN];
int size;
while(1)
{
// scanf("%s",buf);
gets(buf);
size=send(sock_client,buf,DATA_LEN,0);
size=recv(sock_client,buf,DATA_LEN,0);
buf[size]='\0';
printf("%s\n",buf);
}
close(sock_client);
return 1;
}
测试:服务器端:
客户端:
接口函数说明:
函数名:socket头文件:<sys/socket.h>
函数原型:int socket(int dotmain,int type,int protocol)
参数说明:dotmain--协议族(如本例中的AF-INET) type--套接口类型(如本例中的SOCK_STREAM) protocol--这里设置为0
函数功能:创建套接字获得文件描述符
返回值:成功返回文件描述符,否则返回-1
函数名:bind
头文件:<sys/socket.h>
函数原型:int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
参数说明:sockfd--套接字的文件描述符 addr--套接字地址结构指针 addrlen--该地址结构的长度
函数功能:为套接口分配IP和协议端口
返回值:成功返回0,否则返回-1
函数名:listen
头文件:<sys/socket.h>
函数原型:int listen(int sockfd,int backlog)
参数说明:sockfd--套接字文件描述符 backlog--套接口队列的最大连接数
函数功能:等待客户端连接请求
返回值:成功返回0,否则返回-1
函数名:accept
头文件:<sys/socket.h>
函数原型:int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen)
参数说明:sockfd--套接字文件描述符 addr--连接方的套接字地址结构 addrlen--套接字地址的空间
函数功能:返回一个已完成的连接
返回值:成功返回连接方的套接字文件描述符,否则返回-1
函数名:send
头文件:<sys/socket.h>
函数原型:ssize_t send(int sockfd,const void *buf,size_t len,int flags)
参数说明:sockfd--套接字文件描述符 buf--发送数据的地址指针 ;len--数据长度 flags--这里取0
函数功能:发送数据
返回值:发送数据的长度
函数名:recv
头文件:<sys/socket.h>
函数原型:ssize_t(int sockfd,void *buf,size_t len,int flags)
参数说明:sockfd--套接字文件描述符 buf--接收数据的地址指针 len--数据长度 flags--这里取0
函数功能:接收数据
返回值:发送数据的长度
函数名:close
头文件:<unistd.h>
函数原型:int close(int fd)
参数说明:fd--文件描述符
函数功能:关闭文件描述符
返回值:成功返回0,否则返回-1
函数名:connect
头文件:<sys/socket.h>
函数原型:int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen)
函数功能:连接远程地址
参数说明:sockfd--套接字文件描述符 addr--远程地址结构指针 addrlen--该地址结构的空间大小
返回值:成功返回0,否则返回-1
如有问题,请联系zjgsuffddybz@gmail.com