TCP编程的一个小例子

http://blog.youkuaiyun.com/buaa_shang/article/details/10735383


TCP程序的服务器端与客户端的流程图

例子:服务器端等待客户端连接,若连接成功,则用户可以通过客户端向服务器端发送任意字符串,服务器端在收到字符串后,输出相关信息,在把接受到的字符串重新发生给客户端。客户端收到后显示在屏幕上

服务器端:

[cpp]  view plain  copy
  1. #include <sys/stat.h>  
  2. #include <fcntl.h>  
  3. #include <errno.h>  
  4. #include <netdb.h>  
  5. #include <sys/types.h>  
  6. #include <sys/socket.h>  
  7. #include <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #include <string.h>  
  10. #include <stdlib.h>  
  11. #include <stdio.h>  
  12. #include <unistd.h>  
  13.   
  14. #define SERVER_PORT 5555  
  15.   
  16. int main()  
  17. {  
  18.     int serverSocket;  
  19.     struct sockaddr_in server_addr;  
  20.     struct sockaddr_in clientAddr;  
  21.     int addr_len = sizeof(clientAddr);  
  22.     int client;  
  23.     char buffer[1024];  
  24.     int iDataNum;  
  25.   
  26.     //创建服务器端套接字,SOCK_STREAM指的是TCP通信,面向连接的字节流;SOCK_DGRAM是指UDP通信  
  27.     if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)    //创建服务器端套接字,返回值为套接字号  
  28.     {  
  29.         perror("socket");  
  30.         exit(1);  
  31.     }  
  32.   
  33.     bzero(&server_addr, sizeof(server_addr));  
  34. //  memset(server_addr, 0, sizeof(server_addr));  
  35.     server_addr.sin_family = AF_INET;               //AF_INET用来指定当前采用的协议是TCP/IP  
  36.     server_addr.sin_port = htons(SERVER_PORT);      //htons()用于字节序的转换,表示将一个数值从主机字节序转换成网络字节序,保证数据的一致性  
  37.     server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//htons()函数是指16字节的转换,htonl()是32字节序转换  
  38.     if (bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)    //将地址信息与此前创建成功的套接字关联在一起  
  39.     {  
  40.         perror("connect");  
  41.         exit(1);  
  42.     }  
  43.   
  44.     if (listen(serverSocket, 5) < 0) //服务套接字在指定端口监听,以被动的方式等待客户端连接,其中5为请求连接队列的最大长度  
  45.     {  
  46.         perror("listen");  
  47.         exit(1);  
  48.     }  
  49.   
  50.     while (1)  
  51.     {  
  52.         //accept()函数主要是在指定的端口侦听,当客户端的连接请求到来时,维护并完成通信连接的建立,然后在这条链路上进行数据的收发  
  53.         //第一个参数为当前服务套接字,第二个参数用于保存当前客户端的地址信息,第三个参数为客户端地址的长度  
  54.         client = accept(serverSocket, (struct sockaddr *)&clientAddr, (socklen_t *)&addr_len);  
  55.         if (client < 0)  
  56.         {  
  57.             perror("accept");  
  58.             continue;  
  59.         }  
  60.         iDataNum = read(client, buffer, 1024);  
  61.         buffer[iDataNum] = '\0';  
  62.         if (iDataNum < 0)  
  63.         {  
  64.             perror("recv");  
  65.             continue;  
  66.         }  
  67.         printf("\nRecv client data...\n");  
  68.         printf("IP is %s\n", inet_ntoa(clientAddr.sin_addr));  
  69.         printf("Port is %d\n", htons(clientAddr.sin_port));  
  70.         printf("Recv Data is %s, the data length is %d\n", buffer, iDataNum);  
  71.         write(client, buffer, iDataNum);  
  72.     }  
  73.     return 0;  
  74. }  

客户端:

[cpp]  view plain  copy
  1. #include <sys/stat.h>  
  2. #include <fcntl.h>  
  3. #include <errno.h>  
  4. #include <netdb.h>  
  5. #include <sys/types.h>  
  6. #include <sys/socket.h>  
  7. #include <netinet/in.h>  
  8. #include <arpa/inet.h>  
  9. #include <string.h>  
  10. #include <stdlib.h>  
  11. #include <stdio.h>  
  12. #include <unistd.h>  
  13.   
  14. int main()  
  15. {  
  16.     int len;  
  17.     struct sockaddr_in serverAddr;  
  18.     int clientSocket;  
  19.     char sendbuf[200];  
  20.     char recvbuf[200];  
  21.     if ((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)  
  22.     {  
  23.         perror("socket error");  
  24.         return -1;  
  25.     }  
  26.   
  27.     serverAddr.sin_family = AF_INET;  
  28.     serverAddr.sin_port = htons(5555);  
  29.     serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");  
  30.     //connect()函数帮助客户端向指定地址的服务器发起一条TCP连接,成功返回0;第一个参数为连接套接字,第二个为服务器端的地址信息和协议信息  
  31.     if (connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)  
  32.     {  
  33.         perror("connect");  
  34.         exit(1);  
  35.     }  
  36.     printf("connect with destination host...\n");  
  37.     while (1)  
  38.     {  
  39.         printf("Input your Word:>");  
  40.         scanf("%s", sendbuf);       //缺陷:不能传输带空格的句子  
  41.         printf("\n");  
  42.   
  43.         if (strcmp(sendbuf, "quit") == 0)  
  44.             break;  
  45.           
  46.         write(clientSocket, sendbuf, strlen(sendbuf));  
  47.         len = read(clientSocket, recvbuf, 200);  
  48.         recvbuf[len] = '\0';  
  49.         printf("recv data of my word is : %s\n", recvbuf);  
  50.     }  
  51.     close(clientSocket);  
  52.   
  53.     return 0;  
  54. }  

注:有个小问题是为什么客户端不能循环输入?


UDP即无链接编程,和这个类似,一般用在P2P中,主要是创建socket的时候,要指定SOCK——DGRAM.

数据的收发调用sendto()和recvfrom().

0



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值