在Linux下写了个小的socket程序,分为客户端和服务器端,服务端开一个端口(2000),做为一个daemon,等待客户的连接请求.一旦有客户连接,服务器端打印出客户端的IP地址和端口,并且向服务器端发送欢迎信息和时间.下面是服务端的代码(tcpserver.c).由于这只是个简单的程序,所以只用了单线程实现!
/**//* *
* Tcp Server program, It is a simple example only.
* zhengsh 200520602061 2
* when client connect to server, send a welcome message and timestamp in server.
*/
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <time.h>
#define SERVER_PORT 20000 // define the defualt connect port id
#define LENGTH_OF_LISTEN_QUEUE 10 // length of listen queue in server
#define BUFFER_SIZE 255
#define WELCOME_MESSAGE "welcome to connect the server. "
int main(int argc, char** argv)
{
int servfd,clifd;
struct sockaddr_in servaddr,cliaddr;
if ((servfd = socket(AF_INET,SOCK_STREAM, 0 )) < 0 )
{
printf( " create socket error!\n " );
exit( 1 );
}
bzero( & servaddr, sizeof (servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERVER_PORT);
servaddr.sin_addr.s_addr = htons(INADDR_ANY);
if (bind(servfd,( struct sockaddr * ) & servaddr, sizeof (servaddr)) < 0 )
{
printf( " bind to port %d failure!\n " ,SERVER_PORT);
exit( 1 );
}
if (listen(servfd,LENGTH_OF_LISTEN_QUEUE) < 0 )
{
printf( " call listen failure!\n " );
exit( 1 );
}
while ( 1 )
{ // server loop will nerver exit unless any body kill the process
char buf[BUFFER_SIZE];
long timestamp;
socklen_t length = sizeof (cliaddr);
clifd = accept(servfd,( struct sockaddr * ) & cliaddr, & length);
if (clifd < 0 )
{
printf( " error comes when call accept!\n " );
break ;
}
strcpy(buf,WELCOME_MESSAGE);
// inet_ntop(INET_ADDRSTRLEN,cliaddr.sin_addr,buf,BUFFER_SIZE);
printf( " from client,IP:%s,Port:%d\n " ,inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));
timestamp = time(NULL);
strcat(buf, " timestamp in server: " );
strcat(buf,ctime( & timestamp));
send(clifd,buf,BUFFER_SIZE, 0 );
close(clifd);
} // exit
close(servfd);
return 0 ;
}
客户每次用一个随机的端口连接服务器,并接收来自服务器的欢迎信息,然后打印出来(tcpclient).运行的时候接受一个参数,也就是服务器的ip地址.
/**//* Tcp client program, It is a simple example only.
* zhengsh 200520602061 2
* connect to server, and echo a message from server.
*/
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#define SERVER_PORT 20000 // define the defualt connect port id
#define CLIENT_PORT ((20001+rand())%65536) // define the defualt client port as a random port
#define BUFFER_SIZE 255
#define REUQEST_MESSAGE "welcome to connect the server.\n"
void usage(char* name)
{
printf( " usage: %s IpAddr\n " ,name);
}
int main(int argc, char** argv)
{
int servfd,clifd,length = 0;
struct sockaddr_in servaddr,cliaddr;
socklen_t socklen = sizeof (servaddr);
char buf[BUFFER_SIZE];
if (argc < 2 )
{
usage(argv[ 0 ]);
exit( 1 );
}
if ((clifd = socket(AF_INET,SOCK_STREAM, 0 )) < 0 )
{
printf( " create socket error!\n " );
exit( 1 );
}
srand(time(NULL)); // initialize random generator
bzero( & cliaddr, sizeof (cliaddr));
cliaddr.sin_family = AF_INET;
cliaddr.sin_port = htons(CLIENT_PORT);
cliaddr.sin_addr.s_addr = htons(INADDR_ANY);
bzero( & servaddr, sizeof (servaddr));
servaddr.sin_family = AF_INET;
inet_aton(argv[ 1 ], & servaddr.sin_addr);
servaddr.sin_port = htons(SERVER_PORT);
// servaddr.sin_addr.s_addr = htons(INADDR_ANY);
if (bind(clifd, (struct sockaddr* ) &cliaddr, sizeof (cliaddr)) < 0 )
{
printf( " bind to port %d failure!\n " ,CLIENT_PORT);
exit( 1 );
}
if (connect(clifd,( struct sockaddr * ) & servaddr, socklen) < 0 )
{
printf( " can't connect to %s!\n ", argv[ 1 ]);
exit( 1 );
}
length = recv(clifd, buf, BUFFER_SIZE, 0);
if (length < 0)
{
printf( " error comes when recieve data from server %s! ", argv[1] );
exit( 1 );
}
printf( " from server %s :\n\t%s", argv[1], buf);
close(clifd);
return 0;
}
程序在Fedora core 4下通过编译,有几个warining.但是不影响.