免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1389 | 回复: 0
打印 上一主题 下一主题

Socket 入门+ linux协议栈 [复制链接]

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:57:09
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-23 01:29 |只看该作者 |倒序浏览
From: http://topic.csdn.net/u/20110818/11/2ba543bf-a34a-417f-87d7-3567122664a7.html?seed=2089953752&r=75291466#r_75291466

tcp的server socket流程是socket()创建套接字,bind()绑定,listen()监听,accept()接收然后才是send(),recv()什么 的,最后关闭。client是 socket(),connect(),recv(),send()最后close()。

注意一:
Linux服务器 1024 以下的端口号必须以超级管理员身份使用,或者授权。这个和Windows就不一样。
也就是说,楼主如果使用默认的端口号7,则运行你的这个程序应先切换到root身份,然后再这个权限下运行你写的那个程序。
以普通用户身份,系统不会把1024下的端口号给你用的。

//-------
建议在做Linux下网络编程的的时候,实验端口最好在10000以上,因为如果你的Linux装的服务软件多的话,可能会遇到端口号冲突的问题。别让这小问题绊住你。

端口号取值范围 0 - 65535(即2的16次方)



编译 gcc -o TCPEchoClient TCPEchoClient.c DieWithError.c
对于编译好的 程序 ./TCPEchoClient 127.0.0.1 "echo this"  
如果程序运行结果正常 :Recived :echo this 
但是显示 connect refuse 
TCPEchoClient.c
C/C++ code
  1. #include <stdio.h> /* for printf() and fprintf() */
  2. #include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
  3. #include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
  4. #include <stdlib.h> /* for atoi() and exit() */
  5. #include <string.h> /* for memset() */
  6. #include <unistd.h> /* for close() */

  7. #define RCVBUFSIZE 32 /* Size of receive buffer */

  8. void DieWithError(char *errorMessage); /* Error handling function */

  9. int main(int argc, char *argv[])
  10. {
  11.     int sock; /* Socket descriptor */
  12.     struct sockaddr_in echoServAddr; /* Echo server address */
  13.     unsigned short echoServPort; /* Echo server port */
  14.     char *servIP; /* Server IP address (dotted quad) */
  15.     char *echoString; /* String to send to echo server */
  16.     char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */
  17.     unsigned int echoStringLen; /* Length of string to echo */
  18.     int bytesRcvd, totalBytesRcvd; /* Bytes read in single recv()
  19.                                         and total bytes read */

  20.     if ((argc < 3) || (argc > 4)) /* Test for correct number of arguments */
  21.     {
  22.        fprintf(stderr, "Usage: %s <Server IP> <Echo Word> [<Echo Port>]\n",
  23.                argv[0]);
  24.        exit(1);
  25.     }

  26.     servIP = argv[1]; /* First arg: server IP address (dotted quad) */
  27.     echoString = argv[2]; /* Second arg: string to echo */

  28.     if (argc == 4)
  29.         echoServPort = atoi(argv[3]); /* Use given port, if any */
  30.     else
  31.         echoServPort = 7; /* 7 is the well-known port for the echo service */

  32.     /* Create a reliable, stream socket using TCP */
  33.     if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
  34.         DieWithError("socket() failed");

  35.     /* Construct the server address structure */
  36.     memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
  37.     echoServAddr.sin_family = AF_INET; /* Internet address family */
  38.     echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */
  39.     echoServAddr.sin_port = htons(echoServPort); /* Server port */

  40.     /* Establish the connection to the echo server */
  41.     if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
  42.         DieWithError("connect() failed");

  43.     echoStringLen = strlen(echoString); /* Determine input length */

  44.     /* Send the string to the server */
  45.     if (send(sock, echoString, echoStringLen, 0) != echoStringLen)
  46.         DieWithError("send() sent a different number of bytes than expected");

  47.     /* Receive the same string back from the server */
  48.     totalBytesRcvd = 0;
  49.     printf("Received: "); /* Setup to print the echoed string */
  50.     while (totalBytesRcvd < echoStringLen)
  51.     {
  52.         /* Receive up to the buffer size (minus 1 to leave space for
  53.            a null terminator) bytes from the sender */
  54.         if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0)
  55.             DieWithError("recv() failed or connection closed prematurely");
  56.         totalBytesRcvd += bytesRcvd; /* Keep tally of total bytes */
  57.         echoBuffer[bytesRcvd] = '\0'; /* Terminate the */
  58.         printf("%s", echoBuffer); /* Print the echo buffer */
  59.     }

  60.     printf("\n"); /* Print a final linefeed */

  61.     close(sock);
  62.     exit(0);
  63. }



DieWithError.c
C/C++ code
  1. #include <stdio.h> /* for perror() */
  2. #include <stdlib.h> /* for exit() */

  3. void DieWithUserMessage(const char *msg,const char *detail)
  4. {
  5.     fputs(msg,stderr);
  6.     fputs(":",stderr);
  7.     fputs("detail",stderr);
  8.     fputs("\n",stderr);
  9.     exit(1);
  10. }
  11. void DieWithError(char *errorMessage)
  12. {
  13.     perror(errorMessage);
  14.     exit(1);
  15. }


Linux协议栈:
sys_socketcall

Linux 中的 socket 结构是 struct sock,这个结构是在 linux/include/net/sock.h 中定义的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP