socket 编程
来源:互联网 发布:apache日志文件在哪 编辑:程序博客网 时间:2024/06/10 23:33
1、一个简单的socket编程实例
客户端代码:
import java.io.*;
import java.net.*;
public class client
{
public static void main(String args[]) throws Exception
{
Socket socket=new Socket(InetAddress.getLocalHost(),5000);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader wt = new BufferedReader(new InputStreamReader(System.in));
while(true){
String str=wt.readLine();
out.println("!"+str);
out.flush();
if(str.equals("end"))
{break;}
System.out.println(in.readLine());
}
socket.close();
}
}
服务器端代码:
import java.io.*;import java.net.*;
public class server
{
public static void main(String args[]) throws IOException
{
ServerSocket server=new ServerSocket(5000);
Socket socket=server.accept();
System.out.println("has built a link....");
BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter out=new PrintWriter(socket.getOutputStream());
while(true)
{
String str=in.readLine();
System.out.println("Server"+str);
out.println("has received...");
out.flush();
if(str.equals("end"))
break;
}
out.close();
in.close();
socket.close();
server.close();
}
}
2、ICMP协议 tracerouting程序
转自:http://blog.csdn.net/microtong/article/details/3220463
本程序实现Windows下tracert的功能,程序使用原始套接字发送ICMP回显请求报文,本接收ICMP超时差错报文,和ICMP回显应答报文,得到每一跳的路由器IP地址和往返时间。
- //TraceRoute.h
- #ifndef _ITRACERT_H_
- #define _ITRACERT_H_
- #pragma pack(1)
- //IP数据报头
- typedef struct
- {
- unsigned char hdr_len :4; // length of the header
- unsigned char version :4; // version of IP
- unsigned char tos; // type of service
- unsigned short total_len; // total length of the packet
- unsigned short identifier; // unique identifier
- unsigned short frag_and_flags; // flags
- unsigned char ttl; // time to live
- unsigned char protocol; // protocol (TCP, UDP etc)
- unsigned short checksum; // IP checksum
- unsigned long sourceIP; // source IP address
- unsigned long destIP; // destination IP address
- } IP_HEADER;
- //ICMP数据报头
- typedef struct
- {
- BYTE type; //8位类型
- BYTE code; //8位代码
- USHORT cksum; //16位校验和
- USHORT id; //16位标识符
- USHORT seq; //16位序列号
- } ICMP_HEADER;
- //解码结果
- typedef struct
- {
- USHORT usSeqNo; //包序列号
- DWORD dwRoundTripTime; //往返时间
- in_addr dwIPaddr; //对端IP地址
- } DECODE_RESULT;
- #pragma pack()
- //ICMP类型字段
- const BYTE ICMP_ECHO_REQUEST = 8; //请求回显
- const BYTE ICMP_ECHO_REPLY = 0; //回显应答
- const BYTE ICMP_TIMEOUT = 11; //传输超时
- const DWORD DEF_ICMP_TIMEOUT = 3000; //默认超时时间,单位ms
- const int DEF_ICMP_DATA_SIZE = 32; //默认ICMP数据部分长度
- const int MAX_ICMP_PACKET_SIZE = 1024; //最大ICMP数据报的大小
- const int DEF_MAX_HOP = 30; //最大跳站数
- USHORT GenerateChecksum(USHORT* pBuf, int iSize);
- BOOL DecodeIcmpResponse(char* pBuf, int iPacketSize, DECODE_RESULT& stDecodeResult);
- #endif // _ITRACERT_H_
- //TraceRoute.cpp
- /*----------------------------------------------------------
- 功能说明:该程序简单实现了Windows操作系统的tracert命令功能,
- 可以输出IP报文从本机出发到达目的主机所经过的路由信息。
- -----------------------------------------------------------*/
- #include <iostream>
- #include <iomanip>
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include <stdio.h>
- #include "TraceRoute.h"
- #pragma comment(lib,"ws2_32")
- using namespace std;
- int main(int argc, char* argv[])
- {
- //检查命令行参数
- if (argc != 2)
- {
- cerr << "/nUsage: itracert ip_or_hostname/n";
- return -1;
- }
- //初始化winsock2环境
- WSADATA wsa;
- if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
- {
- cerr << "/nFailed to initialize the WinSock2 DLL/n"
- << "error code: " << WSAGetLastError() << endl;
- return -1;
- }
- //将命令行参数转换为IP地址
- u_long ulDestIP = inet_addr(argv[1]);
- if (ulDestIP == INADDR_NONE)
- {
- //转换不成功时按域名解析
- hostent* pHostent = gethostbyname(argv[1]);
- if (pHostent)
- {
- ulDestIP = (*(in_addr*)pHostent->h_addr).s_addr;
- //输出屏幕信息
- cout << "/nTracing route to " << argv[1]
- << " [" << inet_ntoa(*(in_addr*)(&ulDestIP)) << "]"
- << " with a maximum of " << DEF_MAX_HOP << " hops./n" << endl;
- }
- else //解析主机名失败
- {
- cerr << "/nCould not resolve the host name " << argv[1] << '/n'
- << "error code: " << WSAGetLastError() << endl;
- WSACleanup();
- return -1;
- }
- }
- else
- {
- //输出屏幕信息
- cout << "/nTracing route to " << argv[1]
- << " with a maximum of " << DEF_MAX_HOP << " hops./n" << endl;
- }
- //填充目的Socket地址
- sockaddr_in destSockAddr;
- ZeroMemory(&destSockAddr, sizeof(sockaddr_in));
- destSockAddr.sin_family = AF_INET;
- destSockAddr.sin_addr.s_addr = ulDestIP;
- //使用ICMP协议创建Raw Socket
- SOCKET sockRaw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, WSA_FLAG_OVERLAPPED);
- if (sockRaw == INVALID_SOCKET)
- {
- cerr << "/nFailed to create a raw socket/n"
- << "error code: " << WSAGetLastError() << endl;
- WSACleanup();
- return -1;
- }
- //设置端口属性
- int iTimeout = DEF_ICMP_TIMEOUT;
- if (setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO, (char*)&iTimeout, sizeof(iTimeout)) == SOCKET_ERROR)
- {
- cerr << "/nFailed to set recv timeout/n"
- << "error code: " << WSAGetLastError() << endl;
- closesocket(sockRaw);
- WSACleanup();
- return -1;
- }
- //创建ICMP包发送缓冲区和接收缓冲区
- char IcmpSendBuf[sizeof(ICMP_HEADER)+DEF_ICMP_DATA_SIZE];
- memset(IcmpSendBuf, 0, sizeof(IcmpSendBuf));
- char IcmpRecvBuf[MAX_ICMP_PACKET_SIZE];
- memset(IcmpRecvBuf, 0, sizeof(IcmpRecvBuf));
- //填充待发送的ICMP包
- ICMP_HEADER* pIcmpHeader = (ICMP_HEADER*)IcmpSendBuf;
- pIcmpHeader->type = ICMP_ECHO_REQUEST;
- pIcmpHeader->code = 0;
- pIcmpHeader->id = (USHORT)GetCurrentProcessId();
- memset(IcmpSendBuf+sizeof(ICMP_HEADER), 'E', DEF_ICMP_DATA_SIZE);
- //开始探测路由
- DECODE_RESULT stDecodeResult;
- BOOL bReachDestHost = FALSE;
- USHORT usSeqNo = 0;
- int iTTL = 1;
- int iMaxHop = DEF_MAX_HOP;
- while (!bReachDestHost && iMaxHop--)
- {
- //设置IP数据报头的ttl字段
- setsockopt(sockRaw, IPPROTO_IP, IP_TTL, (char*)&iTTL, sizeof(iTTL));
- //输出当前跳站数作为路由信息序号
- cout << setw(3) << iTTL << flush;
- //填充ICMP数据报剩余字段
- ((ICMP_HEADER*)IcmpSendBuf)->cksum = 0;
- ((ICMP_HEADER*)IcmpSendBuf)->seq = htons(usSeqNo++);
- ((ICMP_HEADER*)IcmpSendBuf)->cksum = GenerateChecksum((USHORT*)IcmpSendBuf, sizeof(ICMP_HEADER)+DEF_ICMP_DATA_SIZE);
- //记录序列号和当前时间
- stDecodeResult.usSeqNo = ((ICMP_HEADER*)IcmpSendBuf)->seq;
- stDecodeResult.dwRoundTripTime = GetTickCount();
- //发送ICMP的EchoRequest数据报
- if (sendto(sockRaw, IcmpSendBuf, sizeof(IcmpSendBuf), 0,
- (sockaddr*)&destSockAddr, sizeof(destSockAddr)) == SOCKET_ERROR)
- {
- //如果目的主机不可达则直接退出
- if (WSAGetLastError() == WSAEHOSTUNREACH)
- cout << '/t' << "Destination host unreachable./n"
- << "/nTrace complete./n" << endl;
- closesocket(sockRaw);
- WSACleanup();
- return 0;
- }
- //接收ICMP的EchoReply数据报
- //因为收到的可能并非程序所期待的数据报,所以需要循环接收直到收到所要数据或超时
- sockaddr_in from;
- int iFromLen = sizeof(from);
- int iReadDataLen;
- while (1)
- {
- //等待数据到达
- iReadDataLen = recvfrom(sockRaw, IcmpRecvBuf, MAX_ICMP_PACKET_SIZE,
- 0, (sockaddr*)&from, &iFromLen);
- if (iReadDataLen != SOCKET_ERROR) //有数据包到达
- {
- //解码得到的数据包,如果解码正确则跳出接收循环发送下一个EchoRequest包
- if (DecodeIcmpResponse(IcmpRecvBuf, iReadDataLen, stDecodeResult))
- {
- if (stDecodeResult.dwIPaddr.s_addr == destSockAddr.sin_addr.s_addr)
- bReachDestHost = TRUE;
- cout << '/t' << inet_ntoa(stDecodeResult.dwIPaddr) << endl;
- break;
- }
- }
- else if (WSAGetLastError() == WSAETIMEDOUT) //接收超时,打印星号
- {
- cout << setw(9) << '*' << '/t' << "Request timed out." << endl;
- break;
- }
- else
- {
- cerr << "/nFailed to call recvfrom/n"
- << "error code: " << WSAGetLastError() << endl;
- closesocket(sockRaw);
- WSACleanup();
- return -1;
- }
- }
- //TTL值加1
- iTTL++;
- }
- //输出屏幕信息
- cout << "/nTrace complete./n" << endl;
- closesocket(sockRaw);
- WSACleanup();
- return 0;
- }
- //产生网际校验和
- USHORT GenerateChecksum(USHORT* pBuf, int iSize)
- {
- unsigned long cksum = 0;
- while (iSize>1)
- {
- cksum += *pBuf++;
- iSize -= sizeof(USHORT);
- }
- if (iSize)
- cksum += *(UCHAR*)pBuf;
- cksum = (cksum >> 16) + (cksum & 0xffff);
- cksum += (cksum >> 16);
- return (USHORT)(~cksum);
- }
- //解码得到的数据报
- BOOL DecodeIcmpResponse(char* pBuf, int iPacketSize, DECODE_RESULT& stDecodeResult)
- {
- //检查数据报大小的合法性
- IP_HEADER* pIpHdr = (IP_HEADER*)pBuf;
- int iIpHdrLen = pIpHdr->hdr_len * 4;
- if (iPacketSize < (int)(iIpHdrLen+sizeof(ICMP_HEADER)))
- return FALSE;
- //按照ICMP包类型检查id字段和序列号以确定是否是程序应接收的Icmp包
- ICMP_HEADER* pIcmpHdr = (ICMP_HEADER*)(pBuf+iIpHdrLen);
- USHORT usID, usSquNo;
- if (pIcmpHdr->type == ICMP_ECHO_REPLY)
- {
- usID = pIcmpHdr->id;
- usSquNo = pIcmpHdr->seq;
- }
- else if(pIcmpHdr->type == ICMP_TIMEOUT)
- {
- char* pInnerIpHdr = pBuf+iIpHdrLen+sizeof(ICMP_HEADER); //载荷中的IP头
- int iInnerIPHdrLen = ((IP_HEADER*)pInnerIpHdr)->hdr_len * 4;//载荷中的IP头长
- ICMP_HEADER* pInnerIcmpHdr = (ICMP_HEADER*)(pInnerIpHdr+iInnerIPHdrLen);//载荷中的ICMP头
- usID = pInnerIcmpHdr->id;
- usSquNo = pInnerIcmpHdr->seq;
- }
- else
- return FALSE;
- if (usID != (USHORT)GetCurrentProcessId() || usSquNo !=stDecodeResult.usSeqNo)
- return FALSE;
- //处理正确收到的ICMP数据报
- if (pIcmpHdr->type == ICMP_ECHO_REPLY ||
- pIcmpHdr->type == ICMP_TIMEOUT)
- {
- //返回解码结果
- stDecodeResult.dwIPaddr.s_addr = pIpHdr->sourceIP;
- stDecodeResult.dwRoundTripTime = GetTickCount()-stDecodeResult.dwRoundTripTime;
- //打印屏幕信息
- if (stDecodeResult.dwRoundTripTime)
- cout << setw(6) << stDecodeResult.dwRoundTripTime << " ms" << flush;
- else
- cout << setw(6) << "<1" << " ms" << flush;
- return TRUE;
- }
- return FALSE;
- }
3、和服务器建立TCP连接 SNMP协议监测主机上的这条TCP连接 获取监测的信息
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <Iphlpapi.h>
#include <malloc.h>
#include <Winsock2.h>
#include <stdlib.h>
#include <tchar.h>
#include<windef.h>
LPVOID lpMsgBuf;
#pragma comment(lib, "Iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
char receiveMessage[5000]="";
char sendMessage[512]="";
static char TcpState[][32] =
{
"CLOSED",
"LISTENING",
"SYN_SENT",
"SEN_RECEIVED",
"ESTABLISHED",
"FIN_WAIT",
"FIN_WAIT2",
"CLOSE_WAIT",
"CLOSING",
"LAST_ACK",
"TIME_WAIT"
};
DWORD EnumTCPTable()
{
PMIB_TCPTABLE pTcpTable = NULL;
DWORD dwSize = 0;
DWORD dwRetVal = ERROR_SUCCESS;
struct in_addr rip;
struct in_addr lip;
char szrip[32] = {0};
char szlip[32] = {0};
//获得pTcpTable所需要的真实长度,dwSize
if (GetTcpTable(pTcpTable, &dwSize, TRUE) == ERROR_INSUFFICIENT_BUFFER)
{
pTcpTable = (MIB_TCPTABLE*) malloc ((UINT) dwSize);
}
else
return dwRetVal;
printf("Active Connections\n\n");
printf(" Proto\t%-24s%-24s%s\n","Local Address","Foreign Address","State");
if ((dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)) == NO_ERROR)
{
int i;
for (i = 0; i < (int) pTcpTable->dwNumEntries; i++)
{
rip.S_un.S_addr = pTcpTable->table[i].dwRemoteAddr;
lip.S_un.S_addr = pTcpTable->table[i].dwLocalAddr;
//监听端口,远程主机端口为0,但函数返回是有值的,不知道它是怎么考虑的
if (pTcpTable->table[i].dwState == MIB_TCP_STATE_LISTEN)
pTcpTable->table[i].dwRemotePort = 0;
//dwLocalPort,dwRemotePort 是网络字节
//printf("%d\n",pTcpTable->table[i].dwRemotePort);
//注:htons((short)aaaaa)转换成int类型是bbbbb,通过该条件筛出需要的tcp连接
if(pTcpTable->table[i].dwRemotePort==xxxxxx){
_snprintf(szlip,sizeof(szlip),"%s:%d",inet_ntoa(lip),htons((u_short)pTcpTable->table[i].dwLocalPort));
_snprintf(szrip,sizeof(szrip),"%s:%d",inet_ntoa(rip),htons((u_short)pTcpTable->table[i].dwRemotePort));
printf(" TCP\t%-24s%-24s%s\n",szlip,szrip,TcpState[pTcpTable->table[i].dwState]);
_snprintf(sendMessage,sizeof(sendMessage),"Local Address:%s Foreign Address:%s State:%s "hello world!",szlip
,szrip,TcpState[pTcpTable->table[i].dwState]);}
}
}
else
{
printf("\tCall to GetTcpTable failed.\n");
if (FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwRetVal,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL ))
{
printf("\tError: %s", lpMsgBuf);
}
LocalFree( lpMsgBuf );
}
GlobalFree(pTcpTable);
return dwRetVal;
}
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int ret;
SOCKET sClient; //连接套接字
struct sockaddr_in saServer; //地址信息
char *ptr;
BOOL fSuccess = TRUE;
ptr = (char *)&receiveMessage;
//WinSock初始化
wVersionRequested = MAKEWORD(2, 2); //希望使用的WinSock DLL的版本
ret = WSAStartup(wVersionRequested, &wsaData);
if(ret!=0)
{
printf("WSAStartup() failed!\n");
return -1;
}
//创建Socket,使用TCP协议
sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sClient == INVALID_SOCKET)
{
WSACleanup();
printf("socket() failed!\n");
return;
}
//构建服务器地址信息
saServer.sin_family = AF_INET; //地址家族
saServer.sin_port = htons((short)端口); //注意转化为网络节序
saServer.sin_addr.S_un.S_addr = inet_addr("ip地址");
//连接服务器
ret = connect(sClient, (struct sockaddr *)&saServer, sizeof(saServer));
if (ret == SOCKET_ERROR)
{
printf("connect() failed!\n");
closesocket(sClient); //关闭套接字
WSACleanup();
return -1;
}
//DWORD TcpInfo = EnumTCPTable();
EnumTCPTable();
ret = send (sClient, (char *)&sendMessage, sizeof(sendMessage), 0);
if (ret == SOCKET_ERROR)
{
printf("send() failed!\n");
}
else
printf("send message :%s\n",sendMessage);
ret = recv(sClient, ptr, 5000, 0);
if (ret == SOCKET_ERROR)
{
printf("recv() failed!\n");
return;
}
if (ret == 0) //客户端已经关闭连接
{
printf("Client has closed the connection\n");
return ;
}
printf("receive message:%s\n", receiveMessage);//打印我们接收到的消息。
closesocket(sClient); //关闭套接字
WSACleanup();
}
- socket编程--socket基本概念
- socket编程--socket基本概念
- socket编程
- socket编程
- Socket 编程
- socket编程
- Socket编程
- Socket编程
- Socket编程
- Socket编程
- SOCKET编程
- socket编程
- Socket编程
- socket编程
- Socket 编程
- Socket 编程
- socket 编程
- socket编程
- 《分布式JAVA应用 基础与实践》 第七章 构建可伸缩的系统
- web系统怎么识别登陆的帐户是同一台电脑登陆 用户绑定电脑
- 漫话网络带宽估计
- String和StringBuffer的区别?
- Erlang聊天程序后端(二)
- socket 编程
- 面向对象的特征有哪些?
- POJ 1264 UVA 109 简单的计算几何
- R语言与机器学习学习笔记(分类算法)(1)K-近邻算法
- JAVA WEB
- java中的匿名内部类
- python学习(基础知识)
- ARM汇编指令的一些总结[转]
- T4模版引擎之生成数据库实体类