server端需要做的工作(使用系统调用函数):
(1)创建一个socket; 用socket()
(2)绑定IP地址、端口等信息到socket上; 用bind()
(3)设置允许的最大连接数 用listen()
(4)接收客户端上来的连接 用accept()
(5)收发数据 用recv()和send()或者read()和write()
(6)关闭网络 用close()
server.c
/*
**基于TCP协议的服务器端通信程序
**使用套接口需要执行四个步骤
**(1)分配空间和初始化
**(2)连接
**(3)传送数据
**(4)关闭
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define portnumber 3333
int main( int argc, char *argv[] )
{
int sockfd, temp_fd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int sin_size;
int nbytes;
char buffer[1024];
/* (1)分配空间和初始化 */
/* 服务器端开始建立sockfd描述符 */
if( ( sockfd = socket(AF_INET, SOCK_STREAM, 0) ) == -1 )
{ // AF_INET:IPV4;SOCK_STREAM:TCP
perror("call to socket");
exit(1);
}
/* 服务器端填充 sockaddr结构 */
bzero( &server_addr, sizeof(struct sockaddr_in) ); //server_addr初始化置0
server_addr.sin_family = AF_INET; //internet
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY 表示主机可以是任意IP地址,即服务器程序可以绑定到所有的IP上
//server_addr.sin_addr.s_addr=inet_addr("192.168.1.1"); //用于绑定到一个固定IP,inet_addr用于把数字加格式的ip转化为整形ip
server_addr.sin_port = htons(portnumber); // (将本机器上的short数据转化为网络上的short数据)端口号
/*捆绑sockfd描述符到IP地址**/
if( bind( sockfd, (struct sockaddr *)(&server_addr), sizeof(server_addr) ) == -1 )
{
perror("call to bind");
exit(1);
}
/* 设置允许连接的最大客户端数 */
if( listen( sockfd, 5 ) == -1 )
{
perror("call to listen");
exit(1);
}
printf("Accepting connections ...\n");
while(1)
{
/* 服务器阻塞,直到客户程序建立连接 */
sin_size = sizeof( struct sockaddr_in );
temp_fd = accept( sockfd, (struct sockaddr *)( &client_addr ), &sin_size);
if( temp_fd == -1 )
{
perror("call to accept");
exit(1);
}
fprintf(stderr,"Server get connection from %s\n",inet_ntoa(client_addr.sin_addr));
if( ( nbytes = read( temp_fd, buffer, 1024 ) ) == -1 )
{
perror("call to read");
exit(1);
}
buffer[nbytes] = '\0';
printf( "Server received %s\n", buffer );
/**本次通信结束**/
close(temp_fd);
/*下次循环*/
}
/**结束通信**/
close(sockfd);
exit(0);
}
client端需要做的操作:
(1)创建一个socket; 用socket()
(2)设置要连接的服务器的IP地址和端口等属性
(3)连接服务器 用connect()
(4)收发数据 用send()和recv() 或者read()和write()
(5)关闭网络 用close()
client.c
/*
**TCP客户端通信服务程序
**执行时,需要写入server的ip
** 如: ./client 115.158.92.170
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.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);
}
/*使用hostname查询host名字*/
if( ( host = gethostbyname( argv[1] ) ) == NULL )
{
perror("Error resolving local host\n");
exit(1);
}
/* 客户程序开始建立 sockfd描述符 */
if( ( sockfd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 )
{
perror("Error opening socket");
exit(1);
}
/* 客户端程序填充服务端的资料 */
bzero(&server_addr,sizeof(server_addr)); // 初始化,置0
server_addr.sin_family=AF_INET; // IPV4
server_addr.sin_port=htons(portnumber); // (将本机器上的short数据转化为网络上的short数据)端口号
server_addr.sin_addr=*((struct in_addr *)host->h_addr); // IP地址
/* 客户端程序发起连接请求 */
if( connect( sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr) ) == -1)
{
perror("Error connecting to socket\n");
exit(1);
}
/* 连接成功了 */
printf("Please input char:\n");
/* 发送数据 */
fgets(buffer,1024,stdin);
write(sockfd,buffer,strlen(buffer));
/* 结束通讯 */
close(sockfd);
exit(0);
}