你上面给出的代码其实就是 MSDN 里面的演示代码,不过不完整,只演示了两个函数的使用,我给你看看我写的 TCP 通讯程序,可以在同一个局域网内的两台不同计算机之间聊天 :
这其实就是某本将网络通雀灶余讯的教程里面的例子,不过是我自己重写了一遍,下面给你代码:
========================
下面是公共代码:
========================
#ifndef __CINITSOCK__H__
#define __CINITSOCK__H__
#include <winsock2.h>
#include <iphlpapi.h>
#pragma comment( lib, "ws2_32.lib" )
#pragma comment( lib, "iphlpapi.lib" )
class CInitSock
{
public:
CInitSock( int nMinorVer = 2, int nMajorVer = 2 )
{
WSADATA wsData
WORD wVer = MAKEWORD( nMinorVer, nMajorVer )
if( 0 != 辩和WSAStartup( wVer, &wsData ) ) exit( 0 )
}
~CInitSock( )
{
WSACleanup( )
}
}
#endif
========================
下面是客户端的代码 :
=======================
#include "CInitSock.h"
#include <iostream>
using namespace std
CInitSock g_Sock
void main( )
{
SOCKET sockClient = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP )
if( INVALID_SOCKET == sockClient )
return
sockaddr_in sockAddr
sockAddr.sin_family = AF_INET
sockAddr.sin_port = htons( 4567 )
sockAddr.sin_addr.S_un.S_addr = inet_addr( "127.0.0.1" )
if( -1 == connect( sockClient, ( sockaddr* )&sockAddr, sizeof( sockAddr ) ) )
{
cout << "connect failed" << endl
return
}
while( true )
{
char szBuf[ MAX_PATH ]
ZeroMemory( szBuf, sizeof( szBuf ) )
cout << "You Say : "
cin >> szBuf
if( SOCKET_ERROR == send( sockClient, szBuf, MAX_PATH, 0 ) )
{
cout << "send failed" << endl
return
}
int nRecvLen = recv( sockClient, szBuf, MAX_PATH, 0 )
if( nRecvLen > 0 )
{
// szBuf[ nRecvLen ] = '\0'
cout << "Service Say : " << szBuf << endl <<顷滚 endl
}
else
{
cout << "recv failed" << endl
return
}
}
closesocket( sockClient )
}
======================
下面是服务端的代码:
======================
#include "CInitSock.h"
#include <iostream>
using namespace std
CInitSock g_Sock
void main( )
{
SOCKET sockClient = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP )
if( INVALID_SOCKET == sockClient )
return
sockaddr_in sockAddr
sockAddr.sin_family = AF_INET
sockAddr.sin_port = htons( 4567 )
sockAddr.sin_addr.S_un.S_addr = INADDR_ANY
bind( sockClient, ( sockaddr* )&sockAddr, sizeof( sockAddr ) )
listen( sockClient, SOMAXCONN )
char szBuf[ MAX_PATH ]
sockaddr_in remoteAddr
int nLen = sizeof( sockaddr_in )
SOCKET sock = accept( sockClient, ( sockaddr* )&remoteAddr, &nLen )
while( true )
{
int nRecvLen = recv( sock, szBuf, MAX_PATH, 0 )
if( nRecvLen > 0 )
{
cout << "Client Say : " << szBuf << endl << endl
}
ZeroMemory( szBuf, sizeof( szBuf ) )
cout << "You Say : "
cin >> szBuf
if( SOCKET_ERROR == send( sock, szBuf, MAX_PATH, 0 ) )
{
cout << "send failed" << endl
}
}
closesocket( sock )
closesocket( sockClient )
}
希望能够帮到楼主 。
TCP/IP直接用Socket开发即可(性能要求好的就是使用NIO),或者你去看看袜明森Apache的Mina类库,Mina直接支持了TCP/IP和串口。如果要自己开发串口通信比较麻烦,因为Java层面上不支持串口告亩(硬件) *** 槐腊作要通过javaxcom(win32com.dll)来 *** 作。需要学tcpip。编程语言原本是被设计成专门使用在计算机上的,但它们也可以用来定义算法或者数据结构。正是因为如此,程序员才会试图使程序代码更容易阅读.
TCP协议目谨返雹前是事实上的网络基础。许多更高层的应用协议HTTP,FTP都基于TCP。
TCP协议的学习可以说枯燥无比,尤其是学生阶段,根本不知道用在什么地方,根本不知道重要性是什么。事实上是世雀,基于目前的网络发展和分布式发展,TCP简直就是基础中的基础。许多网络的问题,配置,入侵,防御乃至架构,都涉及到TCP的具体应用及机制。
以下是我总结的TCP学习过程
1. 了解学习TCP协议的重要性和必要性,了解TCP协议为什么被发展出来
推荐这个问题下的各个回答:TCP/IP 协议到底在讲什么?
2. 学习TCP协议的三次握手以及四次挥手,重点了解为什么要三次握手,为什么要四次挥手,在整个过程中状态是如何变迁的。(经典的状态图以及握手挥手图)
a.为什么要三次握手?不是一次,两次或者四次。我们来论证一下,如果只有一次会发生什么情况,a向b发起连接请求,假设b没收到,则b其实完全不知道a发起了请求,而a也完全不知道b收没收到,所以一次握手是不可靠的如果两次握手呢,a向b发起连接请求,b收到a的请求给a回复一个请求,假设此时a收到了b的回复,a知道了b已经ready了,可b完全不知道a是否ready,有可能a并没有收到b的请求,也有可能收到了,但这些b都完全不知道,所以只是单向的建立了连接如果是四次握手呢,其实第2次让a知道b ready了,第三次让b知道a也ready了,第四次完全就是多余了,会浪费网络资源。
b.为什么要四次挥手?不是3次?实际上两边连接完全可以分开看,用2次挥手断开其中一边连接,用另外2次挥手断开另一边的连接,最终完成整个连接关闭。之所以这样设计,是因为有可能某一边数据还未传输完,连接还未关闭。因为TCP被设计为全双工协议,可以任何一边单向发送数据。
1. 握手及挥手过程
2. TCP的状态转换图
3. 学习TCP协议是如何保持可靠性设计的。
主要目的是用来参考,以便在其他通信场合时用作架构和设计的参考
1).包应答序列号及包重组。
面临的问题:网络传输中,会出现数据的破坏,丢包,重复,分片混乱等问题。
本质上,要想保证传输的可靠性,则需要对传输的内容进行验证。
a. 对于网络数据的破坏(比如宇宙射线影响偷笑导致发射火箭的数据中某一位从0变为1),采取的策略是丢弃重新发送,以确保不会出现致命的错误。TCP在自身协议中单独划了一块checksum用于这种校验,校验算法本质上是将整块数据通过某个函数映射到16位的校验位上(比如用字符相加的和来校验)
b. 对于数据传输正确,但是分片乱序,重复等问题,或是丢包,采取的策略并非丢弃而是自行进行包重组。
考虑两种情况:第一种情况是某个包缺少了,导致整个数据中间缺了一段1000字节,那么如何通知到对方自己少了哪一段数据另一种情况是由于网络或者重发机制的原因导致某一个包收到多次,如何把多余的包都排除掉,仅保留已有数据。
TCP在设计时候充分考虑这点,其中SYN和ACK就是用来确保这个过程的,SYN发送的是字节顺序,ACK则应答收到的字节序加1。这样,无论是发送方还是接收方,都可以准确的维护一张发送接收字节的列表。从而可祥帆以知道对方还需要哪些字节,或自己已经接收了哪些字节。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)