我有以下有关异步套接字编程的代码:
public void ServerBeginAceept(ushort ServerPort)
{
try
{
ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, ServerPort);
ServerSocket.Bind(ipEndPoint);
ServerSocket.Listen(MAX_CONNECTIONS);
IAsyncResult result = ServerSocket.BeginAccept(new AsyncCallback(ServerEndAccept), ServerSocket);
}
}
public void ServerEndAccept(IAsyncResult iar)
{
try
{
ServerSocket = (Socket)iar.AsyncState;
CommSocket = ServerSocket.EndAccept(iar);
}
}
public void ClientBeginConnect(string ServerIP, ushort ServerPort)
{
try
{
CommSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(ServerIP), ServerPort);
IAsyncResult result = CommSocket.BeginConnect(ipEndPoint, new AsyncCallback(ClientEndConnect), CommSocket);
}
}
public void ClientEndConnect(IAsyncResult iar)
{
try
{
CommSocket = (Socket)iar.AsyncState;
CommSocket.EndConnect(iar);
OnNetworkEvents eventArgs = new OnNetworkEvents(true, "Connected: " + CommSocket.RemoteEndPoint.ToString(), string.Empty);
OnUpdateNetworkStatusMessage(this, eventArgs);
}
}
代码没有任何问题(我已将其简化,并在此处作为证据证明我正在努力,而不是寻找作业帮助!)
我的问题是:如何从指定的客户端端口与服务器通信?这里的代码都是基于服务器的端口,这很好用。但我想实现与客户端上的特定端口进行通信的代码,而不仅仅是服务器随机生成的代码。
感谢您的时间。
答案 0 :(得分:5)
为什么要使用特定端口?
客户端端口是按设计随机选择的,因为只有一个套接字在没有监听该套接字时,一次可以打开一个端口。
例如,如果您始终在HTTP连接的客户端使用端口80,则该计算机上只有一个套接字可以一次连接到端口80。这意味着HTTP连接不能并行。
答案 1 :(得分:0)
不确定C#,但这是一个有效的解决方案。在C:
/*dl_senderprog.c - debian linux send to server a client, datagram*/
/***********************************************************************
140203 lets see if we can bind to a port
ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
ts7500:/var/www/jon/uvir_sensor_lab/source/socket# vi senderprog_bind.c
ts7500:/var/www/jon/uvir_sensor_lab/source/socket# gcc -g senderprog_bind.c -o senderprog_bind
ts7500:/var/www/jon/uvir_sensor_lab/source/socket# ./senderprog_bind
Sender:Client-Usage: ./senderprog_bind <hostname> <message>
ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
ts7500:/var/www/jon/uvir_sensor_lab/source/socket# ./senderprog_bind 10.0.1.26 "dot,33,22"
MY IP address:10.0.1.242: on port: 1043
Sender: Client-gethostname() is OK...
Sender: Client-socket() sockfd is OK...
Sender: Using port: 14950
Sender: Client-sendto() is OK...
Sender: sent 9 bytes to 10.0.1.26
Sender: Client-sockfd successfully closed!
ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
ts7500:/var/www/jon/uvir_sensor_lab/source/socket# # it worked!!!!!
ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <net/if.h>
/* the port users will be connecting to 14950 is the port on the windows machine
that I have the server running on */
#define TOPORT 14950
#define MYPORT 1043
void my_ip( char *myniccard, char *myipaddr) {
int fd;
struct ifreq ifr;
myipaddr[0]=0;
fd = socket(AF_INET, SOCK_DGRAM, 0);
/* I want to get an IPv4 IP address */
ifr.ifr_addr.sa_family = AF_INET;
/* I want IP address attached to "eth0" */
//strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1);
strncpy(ifr.ifr_name, myniccard, IFNAMSIZ-1);
ioctl(fd, SIOCGIFADDR, &ifr);
close(fd);
/* display result */
sprintf(myipaddr,"%s"
, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
printf("MY IP address:%s: on port: %d\n", myipaddr, MYPORT);
} // my_ip
int main(int argc, char *argv[ ])
{
int sockfd;
/* connectors address information */
struct sockaddr_in their_addr;
struct sockaddr_in localaddr;
char myipaddressm[22]; //buffer for ip address
char *myniccardm ="eth0"; // check with ipconfig for correct ethernet port
struct hostent *he;
int numbytes;
if (argc != 3) {
fprintf(stderr, "Sender:Client-Usage: %s <hostname> <message>\n", argv[0]);
exit(1);
}
my_ip(myniccardm, myipaddressm);
/* get the host info */
if ((he = gethostbyname(argv[1])) == NULL) {
perror("Sender: Client-gethostbyname() error lol!");
exit(1);
}
else
printf("Sender: Client-gethostname() is OK...\n");
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("Sender: Client-socket() error lol!");
exit(1);
}
else
printf("Sender: Client-socket() sockfd is OK...\n");
// Bind to a specific network interface
// (this is unusual, as you normally do not want a specific
// port for the client, but we have a specific server in
// this case that will not accept connects unless its on
// a specific port )
localaddr.sin_family = AF_INET;
localaddr.sin_addr.s_addr = inet_addr(myipaddressm);
localaddr.sin_port = htons(MYPORT); // Any local port will do
bind(sockfd, (struct sockaddr *)&localaddr, sizeof(localaddr));
/* host byte order */
their_addr.sin_family = AF_INET;
/* short, network byte order */
printf("Sender: Using port: %d\n",TOPORT);
their_addr.sin_port = htons(TOPORT);
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
/* zero the rest of the struct */
memset(&(their_addr.sin_zero), '\0', 8);
if((numbytes = sendto(sockfd, argv[2],
strlen(argv[2]),
0,
(struct sockaddr *)&their_addr,
sizeof(struct sockaddr))) == -1) {
perror("Sender: Client-sendto() error lol!");
exit(1);
}
else
printf("Sender: Client-sendto() is OK...\n");
printf("Sender: sent %d bytes to %s\n", numbytes, inet_ntoa(their_addr.sin_addr));
if (close(sockfd) != 0)
printf("Sender: Client-sockfd closing is failed!\n");
else
printf("Sender: Client-sockfd successfully closed!\n");
return 0;
}//main
/*******************************************EOF***********************/