C语言SOCKET问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言SOCKET问题相关的知识,希望对你有一定的参考价值。
我在一个局域网里,我朋友在另一个局域网,通过互联网连接,我想用SOCKET与他连接,直接设置IP地址和端口就可以实现连接了吗?如果可以的话,如果局域网内有另外一台电脑用相同的端口等待连接,那我朋友的请求会成功发到我这里吗?因为我朋友连接我都是用的外网IP+端口,如:14.213.42.81:666!请高手详细解答,我头都要晕了!
一般情况下你是连不上的内网到公网一般都有一个防火墙(和windows防火墙概念可能不太一样,一般在路由器上),负责把内网ip、port转化(映射)成公网的ip、port。“局域网内有另外一台电脑用相同的端口”,一般会被映射成不同的端口,不会冲突。直接监听一个端口,通过公网是连接不到的,即使对上了转化后端口号,一般防火墙也会拦截掉,防火墙分4中类型,有兴趣的可以去查一下资料,有时说的打洞,p2p,其实是指穿透这个防火墙。
如果你的局域网是一个简单的路由器构成,且你能控制这个路由器,里面一般有一个DMZ主机设置,设置成你电脑的ip,它的意思就是把DMZ主机的port对应映射成公网的port(把内网的机器挂在公网上大概就是指这个),之后你的电脑监听一个ip、port,外面的机器就可以连了(ip当然还是要公网的ip,路由器会帮转) 参考技术A 可以实现连接,只要IP地址和端口号给的正确,例如用inet_addr("14.213.42.81")给ip地址,用addressServer.sin_port = htons(port)配端口号。
如果局域网内有另外一台电脑用相同的端口等待连接,那我朋友的请求会成功发到我这里吗?会,你们的IP号不一样,端口号相同没事。 参考技术B 同一局域网内,如果同一路由的话对外的IP地址是一样的。
unix C语言关于socket的recv和send的问题,代码中也有问题
---------------server.c----------------
int main(int argc, char **argv)
int server_fd;
struct sockaddr_in server_addr;
char buff[4096];
char welcome_msg[] = "hello,welcome to my world!\n";
memset(&server_addr, 0x00, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
server_addr.sin_port = htons(PORT);
server_fd = socket(AF_INET ,SOCK_STREAM, 0);
if(server_fd <0)
printf("socket fail: %s\n", strerror(errno));
return -1;
if(bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)))
printf("bind fail: %s \n",strerror(errno)) ;
return -1;
if(listen(server_fd, MAX_LINK) <0)
printf("listen faile: %s \n", strerror(errno));
return -1;
while(1)
struct sockaddr_in link_addr;
int link_fd;
socklen_t link_addr_len;
link_addr_len = sizeof(link_addr);
memset(&link_addr, 0x00, sizeof(link_addr));
link_fd = accept(server_fd, (struct sockaddr*)&link_addr, &link_addr_len);
send(link_fd, welcome_msg, sizeof(welcome_msg), 0);
memset(buff, 0x00, sizeof(buff));
recv(link_fd, buff, MAX_LEN, 0);
printf("%s",buff);
return 0;
---------------client.c----------------
int main(int argc, char **argv)
int link_fd;
struct sockaddr_in link_addr;
struct sockaddr_in server_addr;
char *ipaddr = argv[1];
int port = atoi(argv[2]);
char buff[MAX_BUF];
memset(&link_addr, 0x00, sizeof(link_addr));
memset(&server_addr, 0x00,sizeof(server_addr));
link_addr.sin_family = AF_INET;
link_addr.sin_addr.s_addr = htons(INADDR_ANY);
link_addr.sin_port = htons(0);
server_addr.sin_family = AF_INET;
/* server_addr.sin_addr.s_addr = htons(ipaddr);*/
这里为何要用下面的?
if (inet_aton(ipaddr,&server_addr.sin_addr) <0)
printf("Server IP Address Error!\n");
return -1;
server_addr.sin_port = htons(port);
link_fd = socket(AF_INET, SOCK_STREAM, 0);
if( link_fd <0 )
printf("socket fail: %s\n",strerror(errno));
return -1;
if( bind(link_fd, (struct sockaddr*)&link_addr, sizeof(link_addr)))
printf("bind faile: %s",strerror(errno));
return -1;
if ( connect(link_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) <0 )
printf("connect to server fail: %s \n", strerror(errno));
return -1;
sprintf(buff,"hello, i come from client");
send(link_fd, buff, strlen(buff)+1, 0);
memset(buff, 0x00, sizeof(buff));
recv(link_fd, buff, MAX_BUF, 0);
printf("recv from server :%s", buff);
sleep(10);
close(link_fd);
return 0;
-------------------问题---------------------
为何这个服务端和客户端通信的时候只有client能收到服务器发来的消息,但是服务端却收不到消息?
htons和inet_aton有什么区别?
这个是代码中提问的
---------------------------------
我要的就是要解决我的代码问题,另外贴的都不要,能正确解答的附赠分数
printf("%s",buff);
把它改成
printf("%s\n",buff);
即可。 标准输出是行缓冲的,所以如果打印的内容没有 \n 了话,内容不会真正打印出来,而是留在缓冲中。
至于你client打印时
printf("recv from server :%s", buff);
虽然没有在后面加 \n, 但是你从server发到client的消息里已经带有 \n 了,所以这里没出问题。
关于标准输入输出缓冲相关的更多细节,自己搜一下吧。
htons和inet_aton有什么区别?
htons 是把 主机使用的字节序转成网络字节序 (即入参是整数,返回值也是整数)
而 inet_aton 是吧 ascii 字符串形式的IP地址 转换成 网络字节序的整数。
自己去搜一下网络字节序相关信息。 参考技术A 服务器要想和客户端通信 首先,客户端肯定要是双线程...一个来读 一个来写.. 也就是 一个接受,一个发送...
服务器要多线程 ,每连接一个客户,就多分一个线程,给他用与通信
上面的你可能还没有写,
但你服务器等待到一个客户端的时候是先发送再等待接受,
而客户端也是先发送再等待接受,连上的同时 两边都会 一起发送,这样可能会有数据丢失...
应该是一方发送 另一方再等待接受, 这样才可以通信, 你把客户端或者服务器 send(link_fd, buff, strlen(buff)+1, 0);
和recv(link_fd, buff, MAX_BUF, 0);函数调过来试试追问
这个我也想到过,结果是缓过来依然有问题
追答留下你的Q 我加你,,, 实在不行分步调试,判断每个函数的返回值,逐行加printf 看都执行到那步
追问1181291424我也试过分步调试,想输出send和recv后的返回值,结果这个返回值根本无法打印
说明这个函数没有调用过一样,非常奇怪
把客户端的
send(link_fd, buff, strlen(buff)+1, 0);
把strlen换成sizeof试试..
给你发点代码吧...现在班上编译不了所以无法具体改你的代码,你自己对照吧
#include
#include
#include
#include
#include
#include
#define SERVER_PORT 6688
#define SERVER_IP "192.168.7.191"
int main(int argc, char **argv)
int csfd;
int ret;
char msg[100] = "hello!";
struct sockaddr_in server_info;
server_info.sin_family = AF_INET;
server_info.sin_port = htons(SERVER_PORT);
inet_pton(AF_INET,SERVER_IP,&server_info.sin_addr.s_addr);
csfd = socket(AF_INET,SOCK_STREAM,0);
if (csfd < 0)
printf("socket error!\n");
return 1;
ret = connect(csfd,(struct sockaddr*)&server_info,sizeof(struct sockaddr));
if (ret < 0)
printf("connect server error!\n");
return 2;
while(1)
gets(msg);
ret = write(csfd,msg,strlen(msg));
if (ret <= 0)continue;
bzero(msg,sizeof(msg));
ret = read(csfd,msg,sizeof(msg)-1);
if (ret <= 0)break;
printf("from server :%s\n",msg);
close(csfd);
return 0;
上面的是客户端,服务器的发不上去了...Q加你了,如果需要服务器端的再次追问的时候给你发
这个我要的是要找出我代码的问题,不是另外的代码,我这的书上也有能实现的代码,而且我自己重写也能实现,只是这份代码不能实现,我要找出原因
追答...额,我班上无法调试,没有linux... 能帮你的估计不多了,代码可能就是一点细小的问题,如果自己会了是在没有必要专牛角尖,非要弄明白...重写一份就好,写对了以后用的时候都复制即可,编程不可能所以的代码总是自己重复写..重要的编程思想,明白了也就可以了 ...
以上全是废话,发代码也是因为我是在无能为力了...我在没有编译环境光看代码下能做的真的不多,每次用我也都是复制...或者用别人写好的... 加你Q了,如果想深学网络编程这地方,我记得网络编程是挺厚的一本书那...有的学了
以上是关于C语言SOCKET问题的主要内容,如果未能解决你的问题,请参考以下文章