VB.NET容易做qt局域网聊天工具简单的聊天工具吗?用TCP协议

博客分类:
文件:server.c
PS:第一个连接上服务器的客户端,称为client1,第二个连接上服务器的客户端称为client2
这个服务器的功能是:
1:对于client1,它返回"first",并在client2连接上之后,将client2经过转换后的IP和port发给client1;
2:对于client2,它返回client1经过转换后的IP和port和自身的port,并在随后断开与他们的连接。
#include &stdio.h&
#include &unistd.h&
#include &signal.h&
#include &sys/socket.h&
#include &fcntl.h&
#include &stdlib.h&
#include &errno.h&
#include &string.h&
#include &arpa/inet.h&
#define MAXLINE 128
#define SERV_PORT 8877
//发生了致命错误,退出程序
void error_quit(const char *str)
fprintf(stderr, "%s", str);
//如果设置了错误号,就输入出错原因
if( errno != 0 )
fprintf(stderr, " : %s", strerror(errno));
printf("\n");
int main(void)
int i, res, cur_
int connfd, firstfd,
int count = 0;
char str_ip[MAXLINE];
//缓存IP地址
char cur_inf[MAXLINE];
//当前的连接信息[IP+port]
char first_inf[MAXLINE]; //第一个链接的信息[IP+port]
char buffer[MAXLINE];
//临时发送缓冲区
struct sockaddr_
struct sockaddr_
//创建用于监听TCP协议套接字
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
//把socket和socket地址结构联系起来
res = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
if( -1 == res )
error_quit("bind error");
//开始监听端口
res = listen(listenfd, INADDR_ANY);
if( -1 == res )
error_quit("listen error");
while( 1 )
//接收来自客户端的连接
connfd = accept(listenfd,(struct sockaddr *)&cliaddr, &clilen);
if( -1 == connfd )
error_quit("accept error");
inet_ntop(AF_INET, (void*)&cliaddr.sin_addr, str_ip, sizeof(str_ip));
//对于第一个链接,将其的IP+port存储到first_inf中,
//并和它建立长链接,然后向它发送字符串'first',
if( count == 1 )
cur_port = ntohs(cliaddr.sin_port);
snprintf(first_inf, MAXLINE, "%s %d", str_ip, cur_port);
strcpy(cur_inf, "first\n");
write(connfd, cur_inf, strlen(cur_inf)+1);
//对于第二个链接,将其的IP+port发送给第一个链接,
//将第一个链接的信息和他自身的port返回给它自己,
//然后断开两个链接,并重置计数器
else if( count == 2 )
cur_port = ntohs(cliaddr.sin_port);
snprintf(cur_inf, MAXLINE, "%s %d\n", str_ip, cur_port);
snprintf(buffer, MAXLINE, "%s %d\n", first_inf, cur_port);
write(connfd, buffer, strlen(buffer)+1);
write(firstfd, cur_inf, strlen(cur_inf)+1);
close(connfd);
close(firstfd);
count = 0;
//如果程序运行到这里,那肯定是出错了
error_quit("Bad required");
文件:client.c
PS:第一个连接上服务器的客户端,称为client1,第二个连接上服务器的客户端称为client2
这个程序的功能是:先连接上服务器,根据服务器的返回决定它是client1还是client2,
若是client1,它就从服务器上得到client2的IP和Port,连接上client2,
若是client2,它就从服务器上得到client1的IP和Port和自身经转换后的port,
在尝试连接了一下client1后(这个操作会失败),然后根据服务器返回的port进行监听。
这样以后,就能在两个客户端之间进行点对点通信了。
#include &stdio.h&
#include &unistd.h&
#include &signal.h&
#include &sys/socket.h&
#include &fcntl.h&
#include &stdlib.h&
#include &errno.h&
#include &string.h&
#include &arpa/inet.h&
#define MAXLINE 128
#define SERV_PORT 8877
typedef struct
char ip[32];
//发生了致命错误,退出程序
void error_quit(const char *str)
fprintf(stderr, "%s", str);
//如果设置了错误号,就输入出错原因
if( errno != 0 )
fprintf(stderr, " : %s", strerror(errno));
printf("\n");
int main(int argc, char **argv)
int i, res,
int connfd, sockfd,
unsigned int value = 1;
char buffer[MAXLINE];
struct sockaddr_in servaddr, sockaddr,
if( argc != 2 )
error_quit("Using: ./client &IP Address&");
//创建用于链接(主服务器)的套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
sockaddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET, argv[1], &sockaddr.sin_addr);
//设置端口可以被重用
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
//连接主服务器
res = connect(sockfd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
if( res & 0 )
error_quit("connect error");
//从主服务器中读取出信息
res = read(sockfd, buffer, MAXLINE);
if( res & 0 )
error_quit("read error");
printf("Get: %s", buffer);
//若服务器返回的是first,则证明是第一个客户端
if( 'f' == buffer[0] )
//从服务器中读取第二个客户端的IP+port
res = read(sockfd, buffer, MAXLINE);
sscanf(buffer, "%s %d", other.ip, &other.port);
printf("ff: %s %d\n", other.ip, other.port);
//创建用于的套接字
connfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&connaddr, 0, sizeof(connaddr));
connaddr.sin_family = AF_INET;
connaddr.sin_addr.s_addr = htonl(INADDR_ANY);
connaddr.sin_port = htons(other.port);
inet_pton(AF_INET, other.ip, &connaddr.sin_addr);
//尝试去连接第二个客户端,前几次可能会失败,因为穿透还没成功,
//如果连接10次都失败,就证明穿透失败了(可能是硬件不支持)
while( 1 )
static int j = 1;
res = connect(connfd, (struct sockaddr *)&connaddr, sizeof(connaddr));
if( res == -1 )
if( j &= 10 )
error_quit("can't connect to the other client\n");
printf("connect error, try again. %d\n", j++);
strcpy(buffer, "Hello, world\n");
//连接成功后,每隔一秒钟向对方(客户端2)发送一句hello, world
while( 1 )
res = write(connfd, buffer, strlen(buffer)+1);
if( res &= 0 )
error_quit("write error");
printf("send message: %s", buffer);
//第二个客户端的行为
//从主服务器返回的信息中取出客户端1的IP+port和自己公网映射后的port
sscanf(buffer, "%s %d %d", other.ip, &other.port, &port);
//创建用于TCP协议的套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&connaddr, 0, sizeof(connaddr));
connaddr.sin_family = AF_INET;
connaddr.sin_addr.s_addr = htonl(INADDR_ANY);
connaddr.sin_port = htons(other.port);
inet_pton(AF_INET, other.ip, &connaddr.sin_addr);
//设置端口重用
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
//尝试连接客户端1,肯定会失败,但它会在路由器上留下记录,
//以帮忙客户端1成功穿透,连接上自己
res = connect(sockfd, (struct sockaddr *)&connaddr, sizeof(connaddr));
if( res & 0 )
printf("connect error\n");
//创建用于监听的套接字
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(port);
//设置端口重用
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
//把socket和socket地址结构联系起来
res = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
if( -1 == res )
error_quit("bind error");
//开始监听端口
res = listen(listenfd, INADDR_ANY);
if( -1 == res )
error_quit("listen error");
while( 1 )
//接收来自客户端1的连接
connfd = accept(listenfd,(struct sockaddr *)&sockaddr, &clilen);
if( -1 == connfd )
error_quit("accept error");
while( 1 )
//循环读取来自于客户端1的信息
res = read(connfd, buffer, MAXLINE);
if( res &= 0 )
error_quit("read error");
printf("recv message: %s", buffer);
close(connfd);
浏览: 440574 次
来自: 哈尔滨
$sudo cp MONACO_Linux.ttf /usr/ ...
好YD啊,好YD
1。其中:extman ,extmail下载http://ww ...
repo sync出现“fatal: '../platform ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'局域网必须使用TCP/IP协议吗?_百度知道
局域网必须使用TCP/IP协议吗?
急!!急!!
还是可以使用也可以不适用呢?
我有更好的答案
TCP/IP是用于 计算机网络通信的一系列方法,除此之外还有OSI 模型的一系列协议,除了ISIS用于服务提供商外,基本所有的协议都是基于TCPIP的
采纳率:30%
基本上是的。
不是还有其它协议
比如 ISP 等
为您推荐:
其他类似问题
局域网的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。vb.net TCP多客户端连接,异步方式的一个问题.
下面的连接是以前我发的一个帖子,今天才有时间拿来测试,但是碰到了问题.想问问大家有没有好的解决方法? 以下是代码,是从MSDN上找到的.
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
Imports Microsoft.VisualBasic
Module Module1
Sub Main()
Dim ttt As New AsynchronousSocketListener
AsynchronousSocketListener.Main()
End Module
' State object for reading client data asynchronously
Public Class StateObject
Public workSocket As Socket = Nothing
' Size of receive buffer.
Public Const BufferSize As Integer = 1024
' Receive buffer.
Public buffer(BufferSize) As Byte
' Received data string.
Public sb As New StringBuilder
End Class 'StateObject
Public Class AsynchronousSocketListener
' Thread signal.
Public Shared allDone As New ManualResetEvent(False)
' This server waits for a connection and then uses
asychronous operations to
' accept the connection, get data from the connected client,
' echo that data back to the connected client.
' It then disconnects from the client and waits for another client.
Public Shared Sub Main()
' Data buffer for incoming data.
Dim bytes() As Byte = New [Byte](1023) {}
' Establish the local endpoint for the socket.
Dim ipHostInfo As IPHostEntry = Dns.Resolve(Dns.GetHostName())
Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)
Dim localEndPoint As New IPEndPoint(ipAddress , 11000)
' Create a TCP/IP socket.
Dim listener As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
' Bind the socket to the local endpoint and listen for incoming connections.
listener.Bind(localEndPoint)
listener.Listen(100)
While True
' Set the event to nonsignaled state.
allDone.Reset()
' Start an asynchronous socket to listen for connections.
Console.WriteLine(&Waiting for a connection...&)
listener.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), listener)
' Wait until a connection is made and processed before continuing.
allDone.WaitOne()
End Sub 'Main
Public Shared Sub AcceptCallback(ByVal ar As IAsyncResult)
' Get the socket that handles the client request.
Dim listener As Socket = CType(ar.AsyncState, Socket)
' End the operation.
Dim handler As Socket = listener.EndAccept(ar)
' Create the state object for the async receive.
Dim state As New StateObject
state.workSocket = handler
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
End Sub 'AcceptCallback
Public Shared Sub ReadCallback(ByVal ar As IAsyncResult)
Dim content As String = String.Empty
' Retrieve the state object and the handler socket
' from the asynchronous state object.
Dim state As StateObject = CType(ar.AsyncState, StateObject)
Dim handler As Socket = state.workSocket
' Read data from the client socket.
Dim bytesRead As Integer = handler.EndReceive(ar)
If bytesRead & 0 Then
might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead))
' Check for end-of-file tag. If it is not there, read
' more data.
content = state.sb.ToString()
If content.ToLower.IndexOf(&&eof&&) & -1 Then
' All the data has been read from the
' client. Display it on the console.
Console.WriteLine(&Read {0} bytes from socket. & + vbLf + & Data : {1}&, content.Length, content)
' Echo the data back to the client.
Send(handler, content)
' Not all data received. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state)
End Sub 'ReadCallback
Private Shared Sub Send(ByVal handler As Socket, ByVal data As String)
' Convert the string data to byte data using ASCII encoding.
Dim byteData As Byte() = Encoding.ASCII.GetBytes(data)
' Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), handler)
End Sub 'Send
Private Shared Sub SendCallback(ByVal ar As IAsyncResult)
' Retrieve the socket from the state object.
Dim handler As Socket = CType(ar.AsyncState, Socket)
' Complete sending the data to the remote device.
Dim bytesSent As Integer = handler.EndSend(ar)
Console.WriteLine(&Sent {0} bytes to client.&, bytesSent)
handler.Shutdown(SocketShutdown.Both)
handler.Close()
' Signal the main thread to continue.
allDone.Set()
End Sub 'SendCallback
End Class 'AsynchronousSocketListener
今天趁空测试了一下上面的代码,发现一个问题,就是客户端消息是遵循先进先出原则的,就是说我有好多客户端发送给服务端消息的话,一定要等到最先连接的客户端发送&EOF&字串之后才能继续操作.这样在正常情况下没有问题,但是万一某个客户端发送的字串中由于某种意外的原因没有了&EOF&的话,它后面的所有消息都没法继续,导致服务端一直挂起了...
不知道该怎么来解决这个问题呢?
知识改变命运,奋斗成就人生!
已标记为答案
你好,从上面的程序看应该是没有问题的,请问你的 Client 代码是怎么写的?知识改变命运,奋斗成就人生!
我直接telnet 服务端IP 11000的,出现的情况就是,比如我先后开3个dos窗口telnet,假定分别为win1,win2,win3,我现在在win3输入一串字符,然后输入&EOF&,这个时候程序不退出,而要等到win1也输入&EOF&退出之后,win3才会退出.
你好,我上周用了 msdn 带的 Client 示例连接服务端,不论是从代码是看还是调试结果都没有出现你描述的情况,知识改变命运,奋斗成就人生!
你好,能把Client示例贴给我吗?我在msdn没找到...
知识改变命运,奋斗成就人生!
已标记为答案
谢谢楼上,最近比较忙,一直没机会上来,没有及时设置为答复,sorry!
picat 你好,没关系的,问题解决了就好,不是吗知识改变命运,奋斗成就人生!想找个说得比较全的socket TCP 局域网聊天系统教程【vb.net吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:6,074贴子:
想找个说得比较全的socket TCP 局域网聊天系统教程收藏
如题, 试过跟着不少人的教程写, 跟着跟着也不明白他们在干吗了, 写出来的也不能用呢, 用vb.net有一段时间了, 但是socket 和TCP/IP 这不明白
FoxTable 2017,更低难度,10倍效率,可编译,完美融合B/S和C/S优势,快速开发数据管理软件
我可以教你,不难
登录百度帐号想做一个简单的聊天软件
[问题点数:50分,结帖人fanxingthink]
本版专家分:0
结帖率 100%
CSDN今日推荐
本版专家分:0
结帖率 100%
本版专家分:3288
本版专家分:12492
本版专家分:0
结帖率 100%
本版专家分:0
结帖率 100%
本版专家分:41
本版专家分:0
结帖率 100%
本版专家分:110
本版专家分:52539
2012年2月 扩充话题大版内专家分月排行榜第一2012年1月 挨踢职涯大版内专家分月排行榜第一2011年12月 挨踢职涯大版内专家分月排行榜第一
2012年2月 挨踢职涯大版内专家分月排行榜第三2011年11月 挨踢职涯大版内专家分月排行榜第三2011年10月 挨踢职涯大版内专家分月排行榜第三
本版专家分:20
结帖率 76.92%
本版专家分:36114
本版专家分:0
结帖率 100%
本版专家分:23388
2011年10月 .NET技术大版内专家分月排行榜第二
本版专家分:120
匿名用户不能发表回复!|
CSDN今日推荐}

我要回帖

更多关于 line聊天工具 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信