TCP套接字编程实验报告的简单介绍
TCP Client/Server模式的通信程序设计与实现
我选的第一题,TCP通信
服务器代码:
#include?"stdafx.h"
#includeWinsock2.h
#pragma?comment(lib,"WS2_32.lib")
int?main(int?argc,?char*?argv[])
{
WORD?wVersionRequested;
WSADATA?wsaData;
int?err;
wVersionRequested?=?MAKEWORD(?2,?2?);
err?=?WSAStartup(?wVersionRequested,?wsaData?);
if?(?err?!=?0?)
{
return?-1;
}
if?(?LOBYTE(?wsaData.wVersion?)?!=?2?||
? ? ? HIBYTE(?wsaData.wVersion?)?!=?2?)?{
WSACleanup(?);
return?-1;
}
//这之上的是必须的
SOCKET?sockSer?=?socket(AF_INET,SOCK_STREAM,0);?//TCP套接字
SOCKADDR_IN?AddrSer;?
AddrSer.sin_family=AF_INET;
AddrSer.sin_port=htons(6666);
AddrSer.sin_addr.S_un.S_addr=?inet_addr("127.0.0.1");//本机地址
int?ret?=?bind(sockSer,(SOCKADDR?*)AddrSer,sizeof(SOCKADDR_IN));
if(ret!=0)
return?-1;
listen(sockSer,5);
SOCKADDR_IN?AddrClient;
int?len=sizeof(SOCKADDR_IN);
SOCKET?sockLink=accept(sockSer,(SOCKADDR?*)AddrClient,len);
int?i=0;?char?buf[50];
while(1)
{
memset(buf,0,50);
recv(sockLink,buf,50,0);
printf("%s\n",buf);? //将得到的字符串输出(可不要)
i=strlen(buf);? ?//得到字符串长度?
memset(buf,0,50);
sprintf(buf,"%d",i);?//将int类型i写入char类型buf中
send(sockLink,buf,strlen(buf)+1,0);?//发送长度buf
}
closesocket(sockLink);?closesocket(sockSer);
return?0;
}
客户端代码:
#include?"stdafx.h"
#includeWinsock2.h
#pragma?comment(lib,"ws2_32.lib")
int?main(int?argc,?char*?argv[])
{
WORD?wVersionRequested;
WSADATA?wsaData;
int?err;
wVersionRequested?=?MAKEWORD(?2,?2?);
err?=?WSAStartup(?wVersionRequested,?wsaData?);
if?(?err?!=?0?)
{
return?-1;
}
if?(?LOBYTE(?wsaData.wVersion?)?!=?2?||
? ? ? HIBYTE(?wsaData.wVersion?)?!=?2?)?{
WSACleanup(?);
return?-1;
}
SOCKET?sockClient=?socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN?addr_ser;
addr_ser.sin_family=AF_INET;
addr_ser.sin_port=htons(6666);
addr_ser.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
int?ret?=?connect(sockClient,(SOCKADDR*)addr_ser,sizeof(addr_ser));
if(ret!=0)
return?-1;
char?buf[50];
int?i=0;
while(1)
{
memset(buf,0,50);
gets(buf);? ?//输入字符串
if(strcmp(buf,"再见")==0)
{
?break;
}
else
{
?send(sockClient,buf,strlen(buf)+1,0);
?memset(buf,0,50);
?recv(sockClient,buf,50,0);
?printf("%s\n",buf);
}
}
closesocket(sockClient);
return?0;}
客户端运行结果:
运行时要先运行服务器,在运行客户端。有为题追问吧~~

建立TCP连接以后,如何在一个连接中建立多个通道
TCP server 为什么一个端口可以建立多个连接?
我一直对这个问题有个疑问,今天看到一个论坛里面的讨论,看到了一些回答,解决了我的疑惑,并且我搜索了一些其他资料,记录在这里。
TCP server 可以,TCP client 也可以。一个套接字只能建立一个连接,无论对于 server 还是 client。
TCP server 可以,TCP client 也可以。一个套接字只能建立一个连接,无论对于 server 还是 client。
注意报错消息是:
[Errno 106] (EISCONN) Transport endpoint is already connected?
man 2 connect 说得很清楚了:
Generally, connection-based protocol sockets may successfully connect() only once; connectionless protocol sockets may use connect() multiple times to change their association.?
就是说,TCP 套接字最多只能调用 connect 一次。那么,你的监听套接字调用 connect 了几次?
来点有意思的。
一个套接字不能连接两次,并不代表一个本地地址不能用两次,看!*加粗文字加粗文字*
import socket s = socket.socket()# since Linux 3.9, 见 man 7 socket s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s2 = socket.socket()
s2.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s.bind(('127.0.0.1', 12345))
s2.bind(('127.0.0.1', 12345))# 都可以使用同一本地地址来连接哦 s.connect(('127.0.0.1', 80))
s2.connect(('127.0.0.1', 4321))
netstat -npt | grep 12345(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp ? ? ? ?0 ? ? ?0 127.0.0.1:4321 ? ? ? ? ?127.0.0.1:12345 ? ? ? ? ESTABLISHED 18284/python3
tcp ? ? ? ?0 ? ? ?0 127.0.0.1:12345 ? ? ? ? 127.0.0.1:4321 ? ? ? ? ?ESTABLISHED 4568/python3
tcp ? ? ? ?0 ? ? ?0 127.0.0.1:80 ? ? ? ? ? ?127.0.0.1:12345 ? ? ? ? ESTABLISHED -
tcp ? ? ? ?0 ? ? ?0 127.0.0.1:12345 ? ? ? ? 127.0.0.1:80 ? ? ? ? ? ?ESTABLISHED 4568/python3123456789101112131415161718
端口重用引发的惨案
再接下来分析:?
一个TCP连接需要由四元组来形成,即(src_ip,src_port,dst_ip,dst_port)。?
假设有客户端建立了连接(src_ip1,src_port1,dst_ip1,dst_port1),那么,如果我们还有listen在(src_ip1,src_port1),那么当(dst_ip1,dst_port1)发送消息过来,系统应该把消息给谁?所以就说明了客户端占用了某一端口时,该端口就不能被其它进程listen了。
那么,对于有些童鞋,可能还有这样的疑问,是否一台机器就只能建立65535个连接了(端口16位限制)?非也,一个连接由四元组(src_ip,src_port,dst_ip,dst_port)形式,那么当(src_ip,src_port)一定时,变化的(dst_ip,dst_port)就可以建立更多连接了。
可能有些童鞋还有疑问,作为一个服务器监控一个端口,比如80端口,它为什么可以建立上百万个连接?首先要明白一点,当accept出来后的新socket,它所占用的本地端口依然是80端口,很多新手都以为是一个新的随机端口。由四元组就很容易分析到了,同一个(src_ip,src_port),它所对应的(dst_ip,dst_port)可以无穷变化,这样就可以建立很多个客户端的请求了。
以后遇到奇怪的问题,可以简单的采用四元组原理分析一下了。
网络编程释疑之:单台服务器上的并发TCP连接数可以有多少
一个人也可以建立 TCP 连接呢
希望对你有帮助,祝你好运!
如何编写一个TCP连接?
1、作好编程准备,包括后面要用的头文件,以及一些变量的定义。
2、在终端界面上显示提示信息,告诉TCP运行后的结果,如传送完成、传送了多少字节、速度是多少等。
3、提示客户端用法,如何从键盘输入数据,用什么格式输入,打开套接字,为传送的字节分配内存。
4、用connect函数,指定字节数,时间和遵从的协议。传送完毕,关闭套接字。
5、打开侦听函数,并且等待接收来自客户端的TCP数据。
6、接收完毕,关闭套接字,并且在屏幕显示传输结果。
注意事项:
TCP旨在适应支持多网络应用的分层协议层次结构。 连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。
关于TCP套接字网络编程过程中的一个问题,求指点
把if (!strcmp("tiuq",recvline))改成 if (strstr("tiuq", recvline))试试看,可能是你在终端里面敲的回车符\r也被吸收进去了,然后反转之后变成"\rtiuq",所以strcmp比较不对,换成strstr
实验四,web服务器套接字编程怎么做
1.TCP流式套接字的编程步骤
在使用之前须链接库函数:工程-设置-Link-输入ws2_32.lib,OK!
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//创建套接字(socket)。
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//转换Unsigned short为网络字节序的格式
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
客户端代码如下:
#include Winsock2.h
#include stdio.h
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, wsaData );加载套接字库
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup()( );
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);创建套接字(socket)。
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
connect(sockClient,(SOCKADDR*)addrSrv,sizeof(SOCKADDR));向服务器发出连接请求(connect)。
char recvBuf[100];和服务器端进行通信(send/recv)。
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
send(sockClient,"This is lisi",strlen("This is lisi")+1,0);
closesocket(sockClient);关闭套接字。
WSACleanup()();//必须调用这个函数清除参数
}