◎◎◎◎◎◎◎ 关于TCP服务器端口的问题

bigsail 2007-05-08 04:21:59
TCP服务器创建一个子进程/线程来处理客户机的请求,同时会创建一个新的套接字描述符,
以后具体的通信都使用新的套接字,

我想知道如何获得服务器使用新的套接字与客户机通信的时候,
其与客户机通信的端口号还是不是监听端口号?

各位请指点一下。
...全文
995 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
greengrince 2007-05-09
  • 打赏
  • 举报
回复
理论上大家说得都正确 只是lz的函数使用细节问题
李壮相 2007-05-09
  • 打赏
  • 举报
回复
server打开监听端口,client连接到监听端口时,socket被建立,如上文所说的SOCKET s = accept(...);这个s是唯一的,以后服务器都是通过这唯一的s来通信,服务器怎么就不会区分client?

server当然只能开一个端口,如果client连接一次给一个,那你的电脑还要不要开别的服务呀。client连接的时候也必须指定目标的端口,否则不知道连到哪里去了。
abzhang2 2007-05-09
  • 打赏
  • 举报
回复
首先弄清楚端口是那个的,Server? Client?
thinkinnight 2007-05-09
  • 打赏
  • 举报
回复
套接字和端口不是一样的
killlkilll 2007-05-09
  • 打赏
  • 举报
回复
新的Socket与监听的Socket的端口号不一样的
bigsail 2007-05-09
  • 打赏
  • 举报
回复
感谢各位!
以及vieri_ch(尘雨-自在飞花轻似梦,无边丝雨细如愁)
尘雨 2007-05-09
  • 打赏
  • 举报
回复
通常我们都会初始化指定的监听端口的时候使用sin.port=htons(5150),也就是说地址结构里存放的是网络字节序

同样我们在从地址结构里得到信息的时候,也要注意其原先的字节序是怎样的
尘雨 2007-05-09
  • 打赏
  • 举报
回复
7700=0x1E14

5150=0x141E

也就是说,accept返回的socket(用于recv和send)中得到getsocketname其实还是服务端的端口信息就是5150
尘雨 2007-05-09
  • 打赏
  • 举报
回复
7700是5150的网络字节序
ntohs(7700)==5150

楼主,你调用这个函数的时候,可能忘了ntohs了
bigsail 2007-05-09
  • 打赏
  • 举报
回复

如果服务器不论有多少客户机请求,服务器上只仅仅使用监听端口,那么为什么下面代码(客户/服务器能够正确通信):

accept(.........);
............

struct sockaddr_in sin;
int sinlen=sizeof(sin);
getsockname(accptsock, (struct sockaddr*)&sin, &sinlen);
printf("My addr=%s, port=%d.\n\r",
inet_ntoa(sin.sin_addr),
sin.sin_port);

send(......);
recv(........);


通过 *getsockname()* 获得的端口号不是监听端口号,我监听号是5150,得到的port=7700,而且不论多少客户机,都是显示相同的port=7700。

请问这又是什么原因呢?????
bigsail 2007-05-09
  • 打赏
  • 举报
回复
getpeername//得到远程IP地址和端口号
getsockname//得到本地的IP地址和端口号

我就是调用了这两个函数发现的问题,

对每一个新分配的SOCKET(accept返回的),使用getsockname却总是得到相同的端口号,而且不论又多少客户机都是如此,而且该端口号不是监听端口号。

按照:“ lizhx2000(lee) ” 这个人的说法,
1.服务器端对新的 accept 返回的套接字调用 getsockname 应该得到的是监听端口号,但是实际上不是;
2.客户机这边对套接字调用 getpeername 应该得到服务器上的 *与客户机连接的端口号* ,但是得到的同样不是服务器上的监听端口号,但是得到的这个端口号却与 "1." 相同。


lizhx2000(lee) 的说法没法解释原因。



bigsail 2007-05-08
  • 打赏
  • 举报
回复
获得的端口号不是监听端口号,我监听号是5150,得到的port=7700,而且不论多少客户机,都是显示相同的port
-----------------------
晕~~accept获得的端口是客户连来的,不是你服务器监听的!

唉~建议你还是多看看书,遇到了技术性的问题再来问,这些是基础性的东西

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

申明:上面说指的获得的端口号,不是使用 accept 获得的,而使 getsockname 获得的。
getsockname 函数获得与某个套接字相关的本地协议、地址和端口。
因此,对accept返回的新套接字,使用该函数能够获得新套接字的这些信息。

mynamelj 2007-05-08
  • 打赏
  • 举报
回复
先了解socket模型吧
bigsail 2007-05-08
  • 打赏
  • 举报
回复
服务器这边如果把
getsockname(accptsock, (struct sockaddr*)&sin, &sinlen);
换成:
getpeername(accptsock, (struct sockaddr*)&sin, &sinlen);

却能够正确得到客户机的IP和端口,因此,代码应该没有问题的。
mynamelj 2007-05-08
  • 打赏
  • 举报
回复

获得的端口号不是监听端口号,我监听号是5150,得到的port=7700,而且不论多少客户机,都是显示相同的port
-----------------------
晕~~accept获得的端口是客户连来的,不是你服务器监听的!

唉~建议你还是多看看书,遇到了技术性的问题再来问,这些是基础性的东西
bigsail 2007-05-08
  • 打赏
  • 举报
回复
但是我用所有的网络工具,Sniffer、netstat、防火墙看连接信息,都只有一个监听端口号被使用
bigsail 2007-05-08
  • 打赏
  • 举报
回复
如果只有监听端口,那么为什么下面代码(客户/服务器能够正确通信):

accept(.........);
............

struct sockaddr_in sin;
int sinlen=sizeof(sin);
getsockname(accptsock, (struct sockaddr*)&sin, &sinlen);
printf("My addr=%s, port=%d.\n\r",
inet_ntoa(sin.sin_addr),
sin.sin_port);

send(......);
recv(........);


通过getsockname获得的端口号不是监听端口号,我监听号是5150,得到的port=7700,而且不论多少客户机,都是显示相同的port=7700。

请问这又是什么原因呢?????

lzd 2007-05-08
  • 打赏
  • 举报
回复
服务器这边不会多开一个端口。。还是用监听的端口通信
lzd 2007-05-08
  • 打赏
  • 举报
回复
确定一条正常的TCP连接有四个要素( server ip,server port,client ip,client port )..四个当中任何一个不同即可认为是不同的tcp连接..所以服务器的ip和端口可以相同..但是客户端的端口和ip会不同.
bigsail 2007-05-08
  • 打赏
  • 举报
回复
不是用IP地址嘛,不同客户端的IP地址可能不同

如果相同,还可以根据进程号来区分,是在TDI层实现的
____________________________________________________

我的意思是服务器这边,如果不是为每一个连接分配一个新端口(即:多个套接字公用了一个端口号),
那么服务器如何知道收到的一个TCP包是发给哪个套接字的?
因为在底层协议上只有IP和端口号信息,没有 SOCKET 信息,
套接字如何知道一个TCP数据包是发给哪个SOCKET的呢????
加载更多回复(11)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧