本文目录一览:
- 1、毕业论文《基于socket 的局域网聊天工具》,要求C++语音编写,要有程序,能实现,有文档……
- 2、网上的Java基于Socket文件传输示例,一个客户端一个服务器端一个socket的Util辅助类怎么运行起来啊
- 3、sockettool怎么监听代码
- 4、在同一个计算机上怎么实现socket方法?
- 5、TCP及Socket
- 6、用java的Socket编写的小小小聊天工具,在本机调试成功,但是在两台能互相ping通的电脑却不能连接上
毕业论文《基于socket 的局域网聊天工具》,要求C++语音编写,要有程序,能实现,有文档……
“对图中的那些函数,我这里稍加解释一下。”
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
功能是初始化Windows Socket Dll,在Windows下必须使用它。
参数:
“wVersionRequested”表示版本,可以是1.1、2.2等;
“lpWSAData”指向WSADATA数据结构的指针。
int socket(int family, int type, int protocol);
功能是建立Socket,返回以后会用到的Socket值。如果错误,返回-1。
参数:
“int family”参数指定所要使用的通信协议,取以下几个值:AF_UNIX(Unix内部协议)、AF_INET(Internet协议)、AF_NS Xerox(NS协议)、AF_IMPLINK(IMP连接层),在Windows下只能把“AF”设为“AF_INET”;
“int type”参数指定套接字的类型,取以下几个值:SOCK_STREAM(流套接字)、SOCK_DGRAM (数据报套接字)、SOCK_RAW(未加工套接字)、SOCK_SEQPACKET(顺序包套接字);
“int protocol”参数通常设置为0。
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
功能是把套接字和机器上一定的端口关联起来。
参数:
“sockfd”是调用socket()返回的套接字值;
“my_addr”是指向数据结构struct sockaddr的指针,它保存你的地址,即端口和IP地址信息;
“addrlen”设置为sizeof(struct sockaddr)。
int listen(int sockfd, int backlog);
功能是服务端监听一个端口,直到accept()。在发生错误时返回-1。
参数:
“sockfd”是调用socket()返回的套接字值;
“backlog”是允许的连接数目。大多数系统的允许数目是20,也可以设置为5到10。
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
功能是客户端连接服务端监听的端口。
参数:
“sockfd”是调用socket()返回的套接字值;
“serv_addr”保存着目的地端口和IP 地址的数据结构struct sockaddr;
“addrlen”设置为sizeof(struct sockaddr)。
int accept(int sockfd, void *addr, int *addrlen);
功能是服务端接受客户端的连接请求,并返回一个新的套接字,以后服务端的数据传输就使用这个新的套接字。如果有错误,返回-1。
参数:
“sockfd”是和listen()中一样的套接字值;
“addr”是个指向局部的数据结构sockaddr_in的指针;
“addrlen”设置为sizeof(struct sockaddr_in)。
int send(int sockfd, const void *msg, int len, int flags);
int recv(int sockfd, void *buf, int len, unsigned int flags);
功能是用于流式套接字或数据报套接字的通讯,我们数据的真正传输就由它们完成。
参数:
“sockfd”是发/收数据的套接字值;
“msg”指向你想发送的数据的指针;
“buf”是指向接收数据存放的地址;
“len”是数据的长度;
“flags”设置为 0。
int sendto(int sockfd, const void *msg, int len, unsigned int flags,const struct sockaddr *to, int tolen);
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);
功能和send、recv类似,不过是用于无连接数据报套接字的传输。
int closesocket(int sockfd)
功能是关闭套接字。
参数“sockfd”为要关闭的套接字值。
程序:
“这里的目的是让大家对Socket编程有个整体了解。不用怕,程序我会详细解释的,首先是服务端的程序。其流程是:
socket()→bind()→listen→accept()→recv()/send()→closesocket()
具体代码如下:”
★
#include stdio.h
#include winsock.h
#pragma comment(lib,"Ws2_32")
#define MYPORT 830 /*定义用户连接端口*/
#define BACKLOG 10 /*多少等待连接控制*/
int main()
{
int sockfd, new_fd; /*定义套接字*/
struct sockaddr_in my_addr; /*本地地址信息 */
struct sockaddr_in their_addr; /*连接者地址信息*/
int sin_size;
WSADATA ws;
WSAStartup(MAKEWORD(2,2),ws); //初始化Windows Socket Dll
//建立socket
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
//如果建立socket失败,退出程序
printf("socket error\n");
exit(1);
}
//bind本机的MYPORT端口
my_addr.sin_family = AF_INET; /* 协议类型是INET */
my_addr.sin_port = htons(MYPORT); /* 绑定MYPORT端口*/
my_addr.sin_addr.s_addr = INADDR_ANY; /* 本机IP*/
if (bind(sockfd, (struct sockaddr *)my_addr, sizeof(struct sockaddr))== -1)
{
//bind失败,退出程序
printf("bind error\n");
closesocket(sockfd);
exit(1);
}
//listen,监听端口
if (listen(sockfd, BACKLOG) == -1)
{
//listen失败,退出程序
printf("listen error\n");
closesocket(sockfd);
exit(1);
}
printf("listen...");
//等待客户端连接
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr *)their_addr, sin_size)) == -1)
{
printf("accept error\n");
closesocket(sockfd);
exit(1);
}
printf("\naccept!\n");
//有连接,发送ww0830字符串过去
if (send(new_fd, "ww0830\n", 14, 0) == -1)
{
printf("send error");
closesocket(sockfd);
closesocket(new_fd);
exit(1);
}
printf("send ok!\n");
//成功,关闭套接字
closesocket(sockfd);
closesocket(new_fd);
return 0;
}
对服务端程序的流程概括:
先是初始化Windows Socket Dll: WSAStartup(MAKEWORD(2,2),ws);
然后建立Socket: sockfd = socket(AF_INET, SOCK_STREAM, 0)
再bind本机的MYPORT端口:
my_addr.sin_family = AF_INET; /* 协议类型是INET */
my_addr.sin_port = htons(MYPORT); /* 绑定MYPORT端口 */
my_addr.sin_addr.s_addr = INADDR_ANY; /* 本机IP */
bind(sockfd, (struct sockaddr *)my_addr, sizeof(struct sockaddr))
接下来监听端口: listen(sockfd, BACKLOG)
如果有客户端的连接请求,接收它: new_fd = accept(sockfd, (struct sockaddr *)their_addr, sin_size)
最后发送ww0830字符串过去: send(new_fd, "ww0830\n", 14, 0)
收尾工作,关闭socket: closesocket(sockfd); closesocket(new_fd); ”
编译、执行,就会一直监听830端口
客户端程序了。其流程是:
socket()→connect()→send()/recv()→closesocket()
比服务端更简单吧!其实现代码如下:”
★
#include stdio.h
#include stdio.h
#include winsock.h
#pragma comment(lib,"Ws2_32")
#define PORT 830 /* 客户机连接远程主机的端口 */
#define MAXDATASIZE 100 /* 每次可以接收的最大字节 */
int main(int argc, char *argv[])
{
int sockfd, numbytes;
char buf[MAXDATASIZE];
struct sockaddr_in their_addr; /* 对方的地址端口信息 */
if (argc != 2)
{
//需要有服务端ip参数
fprintf(stderr,"usage: client hostname\n");
exit(1);
}
WSADATA ws;
WSAStartup(MAKEWORD(2,2),ws); //初始化Windows Socket Dll
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
//如果建立socket失败,退出程序
printf("socket error\n");
exit(1);
}
//连接对方
their_addr.sin_family = AF_INET; /* 协议类型是INET */
their_addr.sin_port = htons(PORT); /* 连接对方PORT端口 */
their_addr.sin_addr.s_addr = inet_addr(argv[1]); /* 连接对方的IP */
if (connect(sockfd, (struct sockaddr *)their_addr,sizeof(struct sockaddr)) == -1)
{
//如果连接失败,退出程序
printf("connet error\n");
closesocket(sockfd);
exit(1);
}
//接收数据,并打印出来
if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1)
{
//接收数据失败,退出程序
printf("recv error\n");
closesocket(sockfd);
exit(1);
}
buf[numbytes] = '\0';
printf("Received: %s",buf);
closesocket(sockfd);
return 0;
}
对客户端程序的流程概括:
首先是初始化Windows Socket Dll: WSAStartup(MAKEWORD(2,2),ws);
然后建立Socket: sockfd = socket(AF_INET, SOCK_STREAM, 0)
接着连接服务器方:
their_addr.sin_family = AF_INET; /* 协议类型是INET */
their_addr.sin_port = htons(PORT); /* 连接对方PORT端口 */
their_addr.sin_addr.s_addr = inet_addr(argv[1]); /* 连接对方的IP */
connect(sockfd, (struct sockaddr *)their_addr,sizeof(struct sockaddr))
连接成功就接收数据: recv(sockfd, buf, MAXDATASIZE, 0)
最后把收到的数据打印出来并关闭套接字:
printf("Received: %s",buf); closesocket(sockfd);
编译结束后,运行服务端,然后。客户端 服务端IP 回车
你会看到服务端发来得数据。
那么基本的点对点通信就没问题了。只要两台机器同时包含服务端和客户端,就可以互相通信了。
当然,你也可以将服务端和客户端分开做,专门一个服务器负责用户登录和转发消息。
流程如下:
A客户端发登录消息-----》服务器
服务器验证发送用户消息----》客户端
A客户端想发消息给B客户端----》先发给服务端
服务器得到消息查询B客户端IP并转发消息。(或者B客户端循环发消息询问服务器有无消息)
通信结束。
网上的Java基于Socket文件传输示例,一个客户端一个服务器端一个socket的Util辅助类怎么运行起来啊
服务器(Server)
[java] view plaincopy
package com.socket.sample;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerTest {
int port = 8821;
void start() {
Socket s = null;
try {
ServerSocket ss = new ServerSocket(port);
while (true) {
// 选择进行传输的文件
String filePath = "D:\\lib.rar";
File fi = new File(filePath);
System.out.println("文件长度:" + (int) fi.length());
// public Socket accept() throws
// IOException侦听并接受到此套接字的连接。此方法在进行连接之前一直阻塞。
s = ss.accept();
System.out.println("建立socket链接");
DataInputStream dis = new DataInputStream(
new BufferedInputStream(s.getInputStream()));
dis.readByte();
DataInputStream fis = new DataInputStream(
new BufferedInputStream(new FileInputStream(filePath)));
DataOutputStream ps = new DataOutputStream(s.getOutputStream());
// 将文件名及长度传给客户端。这里要真正适用所有平台,例如中文名的处理,还需要加工,具体可以参见Think In Java
// 4th里有现成的代码。
ps.writeUTF(fi.getName());
ps.flush();
ps.writeLong((long) fi.length());
ps.flush();
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];
while (true) {
int read = 0;
if (fis != null) {
read = fis.read(buf);
// 从包含的输入流中读取一定数量的字节,并将它们存储到缓冲区数组 b
// 中。以整数形式返回实际读取的字节数。在输入数据可用、检测到文件末尾 (end of file)
// 或抛出异常之前,此方法将一直阻塞。
}
if (read == -1) {
break;
}
ps.write(buf, 0, read);
}
ps.flush();
// 注意关闭socket链接哦,不然客户端会等待server的数据过来,
// 直到socket超时,导致数据不完整。
fis.close();
s.close();
System.out.println("文件传输完成");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String arg[]) {
new ServerTest().start();
}
}
客户端工具(SocketTool)
[java] view plaincopy
package com.socket.sample;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
public class ClientSocket {
private String ip;
private int port;
private Socket socket = null;
DataOutputStream out = null;
DataInputStream getMessageStream = null;
public ClientSocket(String ip, int port) {
this.ip = ip;
this.port = port;
}
/** */
/**
* 创建socket连接
*
* @throws Exception
* exception
*/
public void CreateConnection() throws Exception {
try {
socket = new Socket(ip, port);
} catch (Exception e) {
e.printStackTrace();
if (socket != null)
socket.close();
throw e;
} finally {
}
}
public void sendMessage(String sendMessage) throws Exception {
try {
out = new DataOutputStream(socket.getOutputStream());
if (sendMessage.equals("Windows")) {
out.writeByte(0x1);
out.flush();
return;
}
if (sendMessage.equals("Unix")) {
out.writeByte(0x2);
out.flush();
return;
}
if (sendMessage.equals("Linux")) {
out.writeByte(0x3);
out.flush();
} else {
out.writeUTF(sendMessage);
out.flush();
}
} catch (Exception e) {
e.printStackTrace();
if (out != null)
out.close();
throw e;
} finally {
}
}
public DataInputStream getMessageStream() throws Exception {
try {
getMessageStream = new DataInputStream(new BufferedInputStream(
socket.getInputStream()));
return getMessageStream;
} catch (Exception e) {
e.printStackTrace();
if (getMessageStream != null)
getMessageStream.close();
throw e;
} finally {
}
}
public void shutDownConnection() {
try {
if (out != null)
out.close();
if (getMessageStream != null)
getMessageStream.close();
if (socket != null)
socket.close();
} catch (Exception e) {
}
}
}
客户端(Client)
[java] view plaincopy
package com.socket.sample;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class ClientTest {
private ClientSocket cs = null;
private String ip = "localhost";// 设置成服务器IP
private int port = 8821;
private String sendMessage = "Windows";
public ClientTest() {
try {
if (createConnection()) {
sendMessage();
getMessage();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private boolean createConnection() {
cs = new ClientSocket(ip, port);
try {
cs.CreateConnection();
System.out.print("连接服务器成功!" + "\n");
return true;
} catch (Exception e) {
System.out.print("连接服务器失败!" + "\n");
return false;
}
}
private void sendMessage() {
if (cs == null)
return;
try {
cs.sendMessage(sendMessage);
} catch (Exception e) {
System.out.print("发送消息失败!" + "\n");
}
}
private void getMessage() {
if (cs == null)
return;
DataInputStream inputStream = null;
try {
inputStream = cs.getMessageStream();
} catch (Exception e) {
System.out.print("接收消息缓存错误\n");
return;
}
try {
// 本地保存路径,文件名会自动从服务器端继承而来。
String savePath = "E:\\";
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];
int passedlen = 0;
long len = 0;
savePath += inputStream.readUTF();
DataOutputStream fileOut = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(savePath)));
len = inputStream.readLong();
System.out.println("文件的长度为:" + len + "\n");
System.out.println("开始接收文件!" + "\n");
while (true) {
int read = 0;
if (inputStream != null) {
read = inputStream.read(buf);
}
passedlen += read;
if (read == -1) {
break;
}
// 下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比
System.out.println("文件接收了" + (passedlen * 100 / len) + "%\n");
fileOut.write(buf, 0, read);
}
System.out.println("接收完成,文件存为" + savePath + "\n");
fileOut.close();
} catch (Exception e) {
System.out.println("接收消息错误" + "\n");
return;
}
}
public static void main(String arg[]) {
new ClientTest().getMessage();
}
}
测试是成功的,在DOS命令行下编译~~~
sockettool怎么监听代码
改变
有几种方法可以监听代码改变:
1. 使用代码版本控制工具,比如Git,SVN等。这些工具可以实时监听代码变更,并记录变更历史,可以随时查看代码变更情况。
2. 使用代码检查工具,比如SonarQube,PMD等,它们可以对源代码进行定时检查,发现代码变更及可能的问题。
3. 使用自动部署工具,比如Ansible,Chef,Puppet等,它们可以实时监控代码变更,并自动更新目标环境。
4. 通过定义监控和报警机制,如基于日志的监控系统,可以及时发现代码变更,并第一时间就此发出警报。
在同一个计算机上怎么实现socket方法?
首先,需要弄懂socket的工作机制,无需装什么虚拟机。
大致的思路是这样:
一、服务器端,将socket绑定在本地IP的某个端口,如6000;启动监听并开始接受客户端。
二、客户端,创建socket以后,连接到本地IP的6000端口,这样就可以了。
三、然后,双方收发数据。
注意:给本地服务器发送数据,网络协议并不将数据发送到网卡上,所以这种类型的数据流是不会出现在网络上的。其他方面的特性和远端通信是差不多的。
TCP及Socket
计算机网络相关的问题,如果想去了解,前提就是深刻理解网络4/7层模型。
记住并理解,上面每一层。切记,切记,切记。知道一些就可以开始主题,分两个部分TCP和Socket。
TCP是(Tranfer Control Protocol)的简称,在OSI参考模型第四层,也就是端口,到端口的的通信,它是一个可靠的双向连接,一旦建立连接就可以双向数据传输,双方都可以进行发送或接收操作。
最常听说的就是三次握手。是的它说的就是TCP建立连接的过程。具体的步骤如下:
第一步:Server监听端口,状态为:Listen
第二部:Client发送SNY包,请求连接,并将状态改为:SYN_SEND
第三部:Server发送ACK包,和SNY包,同意,并请求连接,状态改为:SYN_RCVD
第四部:Client发送ACK包,Server收到包后,连接建立。双方状态改为:ESTABLISHED
第一步:Client发起FIN包。状态变为:FNI_WAIT_1
第二步:Server发送ACK包。状态变为:CLOSE_WAIT,Client收包后状态变为:FNI_WAIT_2
第三步:Server发送FIN包,状态变为:LAST_ACK。Client收包后状态变为:TIME_WAIT
第四步:Client发送ACK包。双方状态变为:CLOSED
需要注意的是,Client是在收到Server FIN包后两个最大报文时间(2MSL)后变为CLOSED状态的。双方都可以发起断开请求,上面是已先发起请求的是Client。
如何验证上面讲的这些呢?那就是抓包分析,其实日常的开发中也可以通过抓包来发现问题。在这里我简单贴个图看一下TCP的包,这个工具非常强大感兴趣的朋友可以去深入了解一下。
1.可以在这个过滤,通过协议,通过IP,通过端口都可以。
2.这个就是每个包,例子中的这个是个[SYN,ACK]包,就是建立TCP连接的第二次握手
3.被抓取的包对应的网络层,从上到下分别是:物理层、数据链路层、网络层、传输层。
Socket其实就是TCP协议的实现。也就是说它就是TCP的API,当然其实Socket也支持别的协议如:UDP。既然是API那,上面说的其实就是它的原理。下面说一下它的使用。大概说一下。
1.ServerSocket:是服务端来监听的类。监听方法accept()。
2.客户端:创建Socket对象,设定IP和Port
3.当有新的客户端连接时可以通过ServerSocket类获取Socket。而Socket就是我们的通讯渠道。
4.发送和读取数据分别使用OutputStream和InputStream而这两个类是从Socket获取的。
其实Socket的基本使用就是这么简单,但是在其实项目中这样是无法满足需求的。实际上大多数场景都是需要一对多的提供服务。
使用多线程实现多客户端的通信
实现服务器与多个客户端进行通信, 可以接受多个客户端的请求并进行回复
应用多线程来实现服务器与多客户端之间的通信
1、服务器端创建ServerSocket,循环调用accept()等待客户端连接
2、客户端创建一个Socket并请求和服务器端连接
3、服务器端接受客户端请求,创建socket与该客户建立专线连接
4、建立连接的两个socket在一个单独的线程上对话
5、服务器端继续等待新的连接
用java的Socket编写的小小小聊天工具,在本机调试成功,但是在两台能互相ping通的电脑却不能连接上
建议先用一个最简单的程序测试客户端链接服务器,这样可以排除很多干扰,下面两个类已经是客户端和服务器的最简代码了,你先测一下,如果仍不能连接,把异常信息发上来看看。
另:Socket连接容易出问题的地方:
1)端口号冲突,服务器无法启动;
2)IP地址错误,IP地址分本机地址、局域网地址和广域网地址,在不同的环境下使用不同的地址测试,如果错误将无法被客户端访问,还有如果机器安装了多网卡等问题都会引起错误;
3)防火墙禁止Java程序开放端口,不单是服务器机器的软防火墙,局域网的防火墙也可能阻止外部的访问。
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerMain {
public ServerMain() {
try {
ServerSocket ss = new ServerSocket(31647);
Socket s = ss.accept();
System.out.printf("客户端连接成功:\n%s\n", s.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new ServerMain();
}
}
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientMain {
public ClientMain() {
try {
Socket s = new Socket("192.168.1.100", 31647); // 修改IP地址
System.out.println("连接服务器成功!");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new ClientMain();
}
}