这几天一直在弄网络编程。今天终于弄出来了。与大家分享一下经验。 代码如下: /* * server.c-- Create a socket server */ #include #include #include #include #include
int port = 8001;
int main(void) { struct sockaddr_in sin; struct sockaddr_in pin; int sock_descriptor; int temp_sock_descriptor; int address_size; char buf[16384]; int i, len;
sock_descriptor = socket(AF_INET, SOCK_STREAM, 0); if(sock_descriptor == -1) { perror("call to socket"); exit(1); }
bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(port);
if(bind(sock_descriptor, (struct sockaddr *)&sin, sizeof(sin)) == -1) { perror("call to bind"); exit(1); }
if(listen(sock_descriptor,20) == -1) { perror("call to listen"); exit(1); } printf("Accepting connections ...\n");
while(1) { temp_sock_descriptor = accept(sock_descriptor, (struct sockaddr *)&pin, &address_size); if(temp_sock_descriptor == -1) { perror("call to accept"); exit(1); }
if(recv(temp_sock_descriptor, buf, 16384, 0) == -1) { perror("Call to recv"); exit(1); }
printf("Now we starting recived the data ............................................\n"); printf("Recived from client: %s\n", buf); //for this server example,we just convert the characters to upper case:
len = strlen(buf); for(i = 0; i < len; i++) buf = toupper(buf); //convert to input to capital
printf("Chevered recive data from client:%s\n", buf);
if(send(temp_sock_descriptor, buf, len, 0) == -1) { perror("call to send"); exit(1); } close(temp_sock_descriptor); } }
/* * client.c -- the client of the TCP/IP */
#include #include #include #include #include
char *host_name = "127.0.0.1"; int port = 8001;
void main(int argc, char *argv[]) { char buf[8192]; char message[256];
int socket_descriptor; struct sockaddr_in pin; struct hostent *server_host_name;
char *str = "A default test string";
if(argc < 2) { printf("Usage: 'test\" Any test string \"\n"); printf("We will send a default test string.\n"); } else str = argv[1];
if((server_host_name = gethostbyname(host_name)) == 0) { perror("Error resolving local host\n"); exit(1); }
printf("Get host info is ok!\n");
bzero(&pin, sizeof(pin)); pin.sin_family = AF_INET; pin.sin_addr.s_addr = htonl(INADDR_ANY); pin.sin_addr.s_addr = ((struct in_addr *) (server_host_name->h_addr))->s_addr;
pin.sin_port = htons(port);
if((socket_descriptor = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Error opening socket\n"); exit(1); }
if(connect(socket_descriptor, (void*)&pin, sizeof(pin)) == -1) { perror("Error connecting to socket\n"); exit(1); }
printf("Sending message is : \n%s to server...\n", str);
if(send(socket_descriptor, str, strlen(str), 0) == -1) { perror("Error in send\n"); exit(1); }
printf("...sent message... wait for response...\n");
if(recv(socket_descriptor, buf, 8192, 0) == -1) { perror("Error in receiving response from server\n"); exit(1); }
printf("\nResponse from server:\n\n%s\n", buf); close(socket_descriptor); } 编写完这两个文件,然后再编写Make文件以便编译。Makefile文件如下: client server: client.o server.o gcc -o server server.o gcc -o client client.o client.o server.o: client.c server.c gcc -c client.c gcc -c server.c clean: rm -f client server *.o 使用make的目的是在修改代码后能够方便的编译。
完成上面的工作后,在命令行输入make回车即可进行编译,期间可能有些警告信息,不要理他。 你可以打开两个终端,以便于测试。先运行服务器程序等待客户端连接。然后再运行客户端程序。 运行结果如下: 服务器端结果 [hyj@localhost tcpip]$ ./server Accepting connections ... Now we starting recived the data ............................................ Recived from client: This is a test. Chevered recive data from client:THIS IS A TEST. 使用ctrl+C可以终止。 客户端结果 [hyj@localhost tcpip]$ ./client "This is a test." Get host info is ok! Sending message is : This is a test. to server... ...sent message... wait for response...
Response from server:
THIS IS A TEST. 其中可能出现的错误有一下几点: 1.使用了已经被占用的端口; 2.指针错误的使用,尤其是在接收和发送这两个函数上; 3.套界字初始化有问题; 下面介绍其中的几个结构: 1.struct sockaddr{ unsigned short sa_family;//address family,FA_xxx char sa_data[14];//14bytes of protocol address }这个结构一般已经不再使用,常用sockaddr_in代替; 2.struct sockaddr_in{ short int sin_family; unsigned short int sin_port; struct in_addr sin_addr; unsigned char sin_zero[8];//填充0以保持与sockaddr同样的大小 } 3.struct hostent{ char *h_name; //主机的正式名称 char **h_aliases; //别名列表 int h_addrtype;//主机地址类型:AF_xxx int H_length;//主机地址长度:4字节 char **h_addr_list;//主机IP地址列表 }
| |